分塊+數論分塊 xjb亂改 xjb查詢的
阿新 • • 發佈:2022-04-05
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; }