分块板子
昨天写完分块,发现自己写的不行,上网搜了一下分块板子,不大一样(但自我感觉逻辑一样),又学了一遍,今天写了写,主要来发个分块板子(求和的)。
#include<iostream> #include<cmath> using namespace std; int n,m; int ge,shu; int a[1000010],belong[1000010]; int s[1010],tag[1010]; int l[1010],r[1010]; void build(){ for(int i=1;i<=n;i++){ belong[i]=(i-1)/ge+1; s[belong[i]]+=a[i]; } for(int i=1;i<=shu;i++){ l[i]=(i-1)*ge+1; r[i]=i*ge; } r[shu]=n; } void change(int x,int y,int k){ if(belong[x]==belong[y]){ for(int i=x;i<=y;i++){ a[i]+=k; s[belong[i]]+=k; } } else{ for(int i=x;i<=r[belong[x]];i++){ a[i]+=k; s[belong[i]]+=k; } for(int i=l[belong[y]];i<=y;i++){ a[i]+=k; s[belong[i]]+=k; } for(int i=belong[x]+1;i<=belong[y]-1;i++){ tag[i]+=k; s[belong[i]]+=k*ge; } } } void cha(int x,int y){ int sum=0; if(belong[x]==belong[y]){ for(int i=x;i<=y;i++){ sum+=a[i]+tag[belong[i]]; } } else{ for(int i=x;i<=r[belong[x]];i++){ sum+=a[i]+tag[belong[i]]; } for(int i=l[belong[y]];i<=y;i++){ sum+=a[i]+tag[belong[i]]; } for(int i=belong[x]+1;i<=belong[y]-1;i++){ sum+=s[i]; } } cout<<sum<<endl; } int main(){ cin>>n>>m; ge=sqrt(n); shu=n/ge; if(n%ge!=0){ shu++; } for(int i=1;i<=n;i++){ cin>>a[i]; } build(); for(int i=1;i<=m;i++){ int c,x,y,k; cin>>c; if(c==1){ cin>>x>>y>>k; change(x,y,k); } else{ cin>>x>>y; cha(x,y); } } return 0; }