1. 程式人生 > 其它 >分塊+數論分塊 xjb亂改 xjb查詢的

分塊+數論分塊 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;
  }