分块学习笔记
分块学习笔记
区间加:
对于每个区间
区间和:
对于每个区间
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+7;
int tag[N],belongs[N],cnt,a[N],sum[N];
int len;
int n;
void add(int l,int r,int x){
int lid=belongs[l],rid=belongs[r];
if(lid==rid){
for(int i=l;i<=r;i++) a[i]+=x,sum[lid]+=x;
return;
}
for(int i=l;belongs[i]==lid;i++) a[i]+=x,sum[lid]+=x;
for(int i=lid+1;i<rid;i++) tag[i]+=x,sum[i]+=len*x;
for(int i=r;belongs[i]==rid;i--) a[i]+=x,sum[rid]+=x;
}
int query(int l,int r,int p){
int lid=belongs[l],rid=belongs[r];
int ans=0;
if(lid==rid){
for(int i=l;i<=r;i++) ans+=a[i],ans%=p,a[i]+=tag[lid],ans%=p;
return ans%p;
}
for(int i=l;belongs[i]==lid;i++) ans+=a[i],ans%=p,ans+=tag[lid],ans%=p;
for(int i=lid+1;i<rid;i++) ans+=sum[i],ans%=p;
for(int i=r;belongs[i]==rid;i--) ans+=a[i],ans%=p,ans+=tag[rid],ans%=p;
return ans%p;
}
signed main(){
// freopen("data.in","r",stdin);
scanf("%lld",&n);
len=sqrt(n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
belongs[i]=(i-1)/len+1;
sum[belongs[i]]+=a[i];
}
for(int i=1;i<=n;i++){
int op,l,r,c;
scanf("%lld%lld%lld%lld",&op,&l,&r,&c);
if(op==0) add(l,r,c);
else printf("%lld\n",query(l,r,c+1));
}
return 0;
}
整除分块
#include<bits/stdc++.h>
using namespace std;
#define int long long
int division_block(int n){
int res=0;
for(int l=1,r;l<=n;l=r+1){
r=n/(n/l);
res+=n/l*(r-l+1);
}
return res;
}
int n;
signed main(){
cin>>n;
printf("%lld",division_block(n));
return 0;
}
根号算法优化DP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+7;
const int mod=1e9+7;
const int MAXN=2e3+7;
int f[MAXN][N];
int n,k;
int cnt,block_len[N];
void init(){
for(int l=1,r;l<=n;l=r+1){
r=n/(n/l),block_len[++cnt]=r-l+1;
}
}
signed main(){
cin>>n>>k;
init();
for(int i=1;i<=cnt;i++) f[0][i]=1;
for(int i=1;i<=k;i++){
for(int j=1;j<=cnt;j++)
f[i][j]=(f[i][j]+(block_len[j]*f[i-1][cnt-j+1]%mod)%mod)%mod;
for(int j=1;j<=cnt;j++)
f[i][j]=(f[i][j]+f[i][j-1]%mod)%mod;
}
printf("%lld",f[k][cnt]%mod);
return 0;
}
根号
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
int n,m,ans;
int d[N],A[N],B[N],vis[N];
vector<int> G[N];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&A[i],&B[i]);
++d[A[i]],++d[B[i]];
}
for(int i=1;i<=m;i++){
int u=A[i],v=B[i];
if(d[u]>d[v]) swap(u,v);
else if(d[u]==d[v]&&u>v) swap(u,v);
G[u].push_back(v);
}
for(int u=1;u<=n;u++){
for(int v:G[u]) vis[v]=u;
for(int v:G[u]){
for(int w:G[v]) if(vis[w]==u) ++ans;
}
}
printf("%d",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】