当前位置: 首页 > news >正文

数组分块|裴蜀定理

 

优雅的抽象和算法设计让人泪目...

 

裴蜀定理

整数a、b的线性组合ax+by能表示的最小正整数是gcd(a,b),且所有可表示数都是gcd(a,b)的倍数

 

lc1625

枚举轮转到最左边的下标+裴蜀定理

 

枚举所有有效轮转(步长为gcd(b,n)),对奇下标必优化、偶下标按需优化(步长为2时),取字典序最小字符串

 

 class Solution {

public:

    string findLexSmallestString(string s, int a, int b) {

        int n = s.size();

        int step = gcd(b, n);

        int g = gcd(a, 10);

        string ans;

 

        for (int i = 0; i < n; i += step) {

            string t = s.substr(i) + s.substr(0, i);

 

            auto modify = [&](int start) -> void {

                int ch = t[start] - '0';

                int inc = ch % g - ch + 10;

                for (int j = start; j < n; j += 2) {

                    t[j] = '0' + (t[j] - '0' + inc) % 10;

                }

//可以转化为的数字这部分可以 暴力枚举也行

            };

 

            modify(1);

            if (step % 2) 

                modify(0);

            

            if (ans.empty() || t < ans) {

                ans = move(t);

            }

        }

        return ans;

    }

};

move

 std::move 是C++11起的标准库函数,将对象转为右值引用,让赋值/初始化时直接“窃取”原对象资源(而非拷贝),提升效率。

 

BFS遍历所有“奇下标加a”“右移b位”的字符串状态,记录已访问避免重复,取字典序最小结果

class Solution {
public:
    string findLexSmallestString(string s, int a, int b) {
        queue<string> q{{s}};
        unordered_set<string> vis{{s}};
        string ans = s;
        int n = s.size();
        while (!q.empty()) {
            s = q.front();
            q.pop();
            ans = min(ans, s);
            string t1 = s;
            for (int i = 1; i < n; i += 2) {
                t1[i] = (t1[i] - '0' + a) % 10 + '0';
            }


            string t2 = s.substr(n - b) + s.substr(0, n - b);
            for (auto& t : {t1, t2}) {
                if (!vis.count(t)) {
                    vis.insert(t);
                    q.emplace(t);
                }
            }
        }
        return ans;
    }
};
 

 

lc2490

class Solution {
public:
    bool isCircularSentence(string s) {
        if (s[0] != s.back())
            return false;
        for (int i = 1, n = s.length(); i < n - 1; i++)
            if (s[i] == ' ' && s[i - 1] != s[i + 1])
                return false;

        return true;
    }
};

 

lc1360

int year = stoi(date.substr(0, 4));

class Solution {

public:

    // 判断是否为闰年

    bool isLeapYear(int year) {

        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);

    }

 

    // 获取某个月的天数

    int daysInMonth(int year, int month) {

        if (month == 2) {

            return isLeapYear(year) ? 29 : 28;

        }

        if (month == 4 || month == 6 || month == 9 || month == 11) {

            return 30;

        }

        return 31;

    }

 

    // 将日期转换为从 0000-00-00 开始的天数

    int dateToDays(string date) {

        int year = stoi(date.substr(0, 4));

        int month = stoi(date.substr(5, 2));

        int day = stoi(date.substr(8, 2));

 

        int totalDays = 0;

 

        // 计算年的天数

        for (int y = 0; y < year; ++y) {

            totalDays += isLeapYear(y) ? 366 : 365;

        }

 

        // 计算月的天数

        for (int m = 1; m < month; ++m) {

            totalDays += daysInMonth(year, m);

        }

        // 加上日的天数

        totalDays += day;

 

        return totalDays;

    }

 

    int daysBetweenDates(string date1, string date2) {

        int days1 = dateToDays(date1);

        int days2 = dateToDays(date2);

        return abs(days1 - days2);

    }

};

 

 

分块模板

#include <bits/stdc++.h>
using namespace std;

vector<long long> a, b, lazy;

struct SqrtDecomposition {
  const int block_size, n;
  vector<int> ls, rs;
  vector<bool> to_be_eval;
  vector<vector<pair<int,int>>> first;

  explicit SqrtDecomposition(const int n_)
      : block_size((int)max(1.0, floor(sqrt((double)n_)))),
        n((n_ + block_size - 1) / block_size) {
    ls.resize(n);
    rs.resize(n);
    to_be_eval.assign(n, false);
    first.resize(n);
    for (int i = 0; i < n; ++i) {
      ls[i] = block_size * i;
      rs[i] = (i + 1 == n ? n_ : block_size * (i + 1));
      first[i].reserve((rs[i] - ls[i]) * 2);
    }
  }

  void rebuild_block(int b) {
  vector<pair<int,int>> tmp;
  tmp.reserve(rs[b] - ls[b]);
  for (int i = ls[b]; i < rs[b]; ++i) tmp.emplace_back((int)a[i], i);
  sort(tmp.begin(), tmp.end(), [](const pair<int,int>& x, const pair<int,int>& y){
    if (x.first != y.first) return x.first < y.first;
    return x.second < y.second;
  });
  auto &mp = first[b];
  mp.clear();
  mp.reserve(tmp.size());
  int last_key = INT_MIN;
  for (auto &p : tmp) {
    if (p.first != last_key) {
      last_key = p.first;
      mp.emplace_back(p.first, p.second);
    }
  }
}

  void build_maps() {
    for (int b = 0; b < n; ++b) rebuild_block(b);
  }

  inline int get_real(int idx) const {
    int blk = idx / block_size;
    return (int)(a[idx] + lazy[blk]);
  }

  int find_leftmost_equal(int uptoIdx, int target) const {
  int br = uptoIdx / block_size;
  for (int b = 0; b < br; ++b) {
    int key = target - (int)lazy[b];
    const auto &vec = first[b];
    auto it = lower_bound(vec.begin(), vec.end(), key,
      [](const pair<int,int>& p, int val){ return p.first < val; });
    if (it != vec.end() && it->first == key) return it->second;
  }
  int key_lazy = (int)lazy[br];
  for (int i = ls[br]; i <= uptoIdx; ++i) {
    if ((int)(a[i] + key_lazy) == target) return i;
  }
  return -1;
}

  void range_add_and_fix(int l, int r, int val) {
    if (r <= l) return;
    const int b_l = l / block_size, b_r = (r - 1) / block_size;
    update(l, r, val);
    if (b_l == b_r) {
      rebuild_block(b_l);
    } else {
      if (l != ls[b_l]) rebuild_block(b_l);
      if (r != rs[b_r]) rebuild_block(b_r);
    }
  }

  template <typename T>
  void partial_update(const int idx, const T val) {
    a[idx] += val;
    b[idx / block_size] += val;
  }

  template <typename T>
  void total_update(const int idx, const T val) {
    lazy[idx] += val;
    to_be_eval[idx] = true;
  }

  template <typename T>
  void update(const int l, const int r, const T val) {
    if (r <= l) return;
    const int b_l = l / block_size, b_r = (r - 1) / block_size;
    if (b_l < b_r) {
      if (l == ls[b_l]) {
        total_update(b_l, val);
      } else {
        for (int i = l; i < rs[b_l]; ++i) {
          partial_update(i, val);
        }
      }
      for (int i = b_l + 1; i < b_r; ++i) {
        total_update(i, val);
      }
      if (r == rs[b_r]) {
        total_update(b_r, val);
      } else {
        for (int i = ls[b_r]; i < r; ++i) {
          partial_update(i, val);
        }
      }
    } else {
      for (int i = l; i < r; ++i) {
        partial_update(i, val);
      }
    }
  }

  template <typename T>
  void partial_query(const int idx, T* val) {
    const int block = idx / block_size;
    if (to_be_eval[block]) {
      for (int i = ls[block]; i < rs[block]; ++i) {
        partial_update(i, lazy[block]);
      }
      lazy[block] = 0;
      to_be_eval[block] = false;
      const_cast<SqrtDecomposition*>(this)->rebuild_block(block);
    }
    *val += a[idx];
  }

  template <typename T>
  void total_query(const int idx, T* val) {
    *val += b[idx] + lazy[idx] * (rs[idx] - ls[idx]);
  }

  template <typename T>
  T query(const int l, const int r, const T id) {
    const int b_l = l / block_size, b_r = (r - 1) / block_size;
    T res = id;
    if (b_l < b_r) {
      if (l == ls[b_l]) {
        total_query(b_l, &res);
      } else {
        for (int i = l; i < rs[b_l]; ++i) {
          partial_query(i, &res);
        }
      }
      for (int i = b_l + 1; i < b_r; ++i) {
        total_query(i, &res);
      }
      if (r == rs[b_r]) {
        total_query(b_r, &res);
      } else {
        for (int i = ls[b_r]; i < r; ++i) {
          partial_query(i, &res);
        }
      }
    } else {
      for (int i = l; i < r; ++i) {
        partial_query(i, &res);
      }
    }
    return res;
  }
};

class Solution {
public:
    int longestBalanced(vector<int>& nums) 
    {
        int n=nums.size();
        int N=n+1;
        SqrtDecomposition sd(N);
        a.assign(N,0);
        b.assign(sd.n,0);
        lazy.assign(sd.n,0);
        sd.build_maps();
        int MAXV=100000;
        vector<int> last(MAXV+1,-1);
        int ans=0;
        for(int r=0;r<n;r++){
            int x=nums[r];
            int pre=last[x];
            int d=(x&1)?+1:-1;
            sd.range_add_and_fix(pre+1,r+1,d);
            last[x]=r;
            int t=sd.get_real(r+1);
            int j=sd.find_leftmost_equal(r,t);
            if(j!=-1)
                ans=max(ans,r-j+1);
        }
        return ans;
        
    }
};

 

http://www.dtcms.com/a/503855.html

相关文章:

  • 中交上航建设网站wordpress 插件发文章
  • Linux中进程创建和缓存对象初始化fork_init、proc_caches_init和buffer_init
  • 学校网站的作用和意义珠海仿站定制模板建站
  • 云原生网络基础:IP、端口与网关实战
  • 郑州网站优化平台做网站需要营业执照吗
  • 企业app商城开发网站建设wordpress userpro
  • C++与C#使用GDI+创建PNG并旋转文本的对比实现
  • 动图在线制作网站烟台广告公司网站建设
  • react.js做的网站学室内装修设计
  • 如何处理大数处理技巧(vpa函数
  • 设计模式举例
  • 【Spring Security】安全过滤链
  • 小区媒体网站建设wordpress简易主题
  • 手机网站经典案例wordpress负载均衡上传附件
  • 银川网站建站中企动力做的网站价格区间
  • 兴义网站开发杭州赛虎网站建设
  • 数据库基础概念体系梳理
  • Kotlin Flow 的使用
  • 网站如何做seo上海网站推广方法
  • Qwen2.5技术报告解读:Qwen2.5 Technical Report
  • 操作系统:进程同步问题(一)
  • Linux---终端 I/O 控制接口开发<termios.h>终端输入输出系统
  • Linux 之 【Linux权限】
  • 网站建设策划书范文案例重庆百度关键词推广
  • 健身器材 网站模版wordpress用户系统
  • 两款实用工具分享:下载与网速测试的轻量级解决方案
  • DVWA靶场实战:Web四大经典漏洞攻防全解析
  • 海外网站测速本地网站建设开发信息大全
  • PowerCat命令操作:PowerShell版的Netcat在渗透测试中的应用
  • 域名注册最好的网站南京设计公司前十名