分块:
- 把n分成sqrt(n)块, 中间整体修改,2边暴力修改即可, 修改,查询的复杂度为3sqr(n);
- 比线段树好写一些?
- 当然整体的修改的时候,有时候要用 lz 去处理,
- 和势能线段树有共同的思想.
模板:
建块:
cin>>n; int d=sqrt(n); int kn=0; for(ri i=1;i<=n;i++) p[i].l=n,p[i].r=0; for(ri i=1;i<=n;i++) { cin>>val[i]; int a=i/d+1;kn=max(kn,a); p[a].val+=val[i]; p[a].l=min(i,p[a].l); p[a].r=max(p[a].r,i); }View Code
处理:
cin>>m; for(ri i=1;i<=m;i++) { int op,a,b; cin>>op>>a>>b; if(a>b) swap(a,b); if(op==0) { for(ri now=a;now<=b;now=p[now/d+1].r+1) { // cout<<now<<"\n"; int tmp=now/d+1; if(p[tmp].r<=b&&now==p[tmp].l) { p[tmp].cnt++; } else { if(p[tmp].cnt) xiu(tmp); if(p[tmp].flag) { continue; } for(ri j=now;j<=min(p[tmp].r,b);j++) { p[tmp].val-=val[j]; val[j]=sqrt(val[j]); p[tmp].val+=val[j]; } if(p[tmp].r-p[tmp].l+1==p[tmp].val) p[tmp].flag=1; } } } else { long long ans=0; for(ri now=a;now<=b;now=p[now/d+1].r+1) { int tmp=now/d+1; if(p[tmp].r<=b&&now==p[tmp].l) { if(p[tmp].flag) ans+=p[tmp].val; else { if(p[tmp].cnt) xiu(tmp); ans+=p[tmp].val; } } else { if(p[tmp].cnt) xiu(tmp); if(p[tmp].flag) { ans+=min(p[tmp].r,b)-now+1; continue; } for(ri j=now;j<=min(p[tmp].r,b);j++) { ans+=val[j]; } } } cout<<ans<<"\n"; }View Code
例题:
思路:
- 势能线段树的思想,很快就会变成1, 于是就不用处理了
#include <bits/stdc++.h> using namespace std; #define ri register int #define M 2000005 struct dian{ int l,r; long long val; int cnt=0; int flag=0; }p[M]; long long val[M]; int n,m; void xiu(int a) { if(p[a].flag) return ; p[a].val=0; for(ri i=p[a].l;i<=p[a].r;i++) { for(ri j=1;j<=p[a].cnt;j++) { val[i]=sqrt(val[i]); if(val[i]==1) break; } p[a].val+=val[i]; } p[a].cnt=0; if(p[a].val==(p[a].r-p[a].l+1)) p[a].flag=1; } int main(){ ios::sync_with_stdio(false); cin.tie(0);cout.tie(0);/////////////////////////////////////////// cin>>n; int d=sqrt(n); int kn=0; for(ri i=1;i<=n;i++) p[i].l=n,p[i].r=0; for(ri i=1;i<=n;i++) { cin>>val[i]; int a=i/d+1;kn=max(kn,a); p[a].val+=val[i]; p[a].l=min(i,p[a].l); p[a].r=max(p[a].r,i); } cin>>m; for(ri i=1;i<=m;i++) { int op,a,b; cin>>op>>a>>b; if(a>b) swap(a,b); if(op==0) { for(ri now=a;now<=b;now=p[now/d+1].r+1) { // cout<<now<<"\n"; int tmp=now/d+1; if(p[tmp].r<=b&&now==p[tmp].l) { p[tmp].cnt++; } else { if(p[tmp].cnt) xiu(tmp); if(p[tmp].flag) { continue; } for(ri j=now;j<=min(p[tmp].r,b);j++) { p[tmp].val-=val[j]; val[j]=sqrt(val[j]); p[tmp].val+=val[j]; } if(p[tmp].r-p[tmp].l+1==p[tmp].val) p[tmp].flag=1; } } } else { long long ans=0; for(ri now=a;now<=b;now=p[now/d+1].r+1) { int tmp=now/d+1; if(p[tmp].r<=b&&now==p[tmp].l) { if(p[tmp].flag) ans+=p[tmp].val; else { if(p[tmp].cnt) xiu(tmp); ans+=p[tmp].val; } } else { if(p[tmp].cnt) xiu(tmp); if(p[tmp].flag) { ans+=min(p[tmp].r,b)-now+1; continue; } for(ri j=now;j<=min(p[tmp].r,b);j++) { ans+=val[j]; } } } cout<<ans<<"\n"; } } return 0; }View Code
标签:势能,val,分块,int,max,kn,long,ri,模板 From: https://www.cnblogs.com/Lamboofhome/p/16893495.html