加载中...

分块+数论分块 xjb乱改 xjb查询的

build(){
  block=sqrt(n);//block表示每块的长度大小
  num=n/block;if(n%block) num++; //num表示分块的个数 可能多出一点 所以+1
  for(int i=1;i<=num;i++){
    l[i]=(i-1)*block()+1,r[i]=i*block;
  }
  r[num]=n;
  for(int i=1;i<=n;i++)
      belong[i]=(i-1)/block+1;//belong 表示每个i 所存在的位置


}
 
int d[maxd]


数论分块 a[i]=n%i![](https://img2022.cnblogs.com/blog/2525875/202204/2525875-20220405163130131-672314641.png)
i为1~n的数
结论:
1.对于一个块来说i为左端点
2.右端点为 r= n/(n/i) 所以下一块的左端点为n/(n/i)+1
3.n/i 代表有多少块 按i为左端点能分多少块
4.n/(n/i) 代表每块的长度 (左端点为i的这一块情况下)

广工 a题 https://ac.nowcoder.com/acm/contest/30896/A

取模

#include<iostream>
using namespace std;
int main()
{
    int n, m; cin>> n >> m;
    while(m--) {
    	int l, r; cin >> l >> r;
        int ans = 0;
        // [l, r]区间,找到其中分块的每一块左端点,维护最大值
        for (int i = l; i <= r; i = n / (n / i) + 1) {
        	ans = max(ans, n % i);
        }
        cout << ans << endl;
    }
}

上海理工大学 k题 取模https://ac.nowcoder.com/acm/contest/30532/K

  #include"bits/stdc++.h"
  using namespace std;
  typedef long long ll;
  const int mod=998244353;
  const int inv2=(998244353+1)/2;
  ll n;
  int main(){
  	cin>>n;
  	ll ans=(n % mod)*(n % mod) %mod;
  	for(ll i=1,r;i<=n;i=r+1){
  		r=n/(n/i);//相同商的右端点
		ans-=(n/i)%mod*((r+i)%mod)%mod*((r+1-i)%mod)%mod*inv2%mod; 
  		ans=(ans%mod+mod)%mod;
	  }
	  cout<<ans<<'\n';
	  return 0;
  } 

posted @ 2022-04-05 17:19  liang302  阅读(37)  评论(0编辑  收藏  举报