洛谷 P2801 教主的魔法 题解
刚看到这道题的时候用了个树状数组优化前缀和差分的常数优化竟然AC了?(这数据也太水了吧~)
本人做的第一道分块题,调试了好久好久,最后竟然没想到二分上还会出错!(一定要注意)仅此纪念;
#include <bits/stdc++.h> #pragma GCC optimize(2) using namespace std; int a[1000010],b[1000010],belong[1000010]; //原来的 int lazy[1000010],l[1000010],r[1000010]; //块上的 int block,tot,n,m; void build() { block=sqrt(n); tot=n/block; if(n%block){ ++tot; } for(register int i=1;i<=n;i++){ b[i]=a[i]; belong[i]=(i-1)/block+1; } for(register int i=1;i<=tot;i++){ l[i]=(i-1)*block+1; r[i]=i*block; } r[tot]=n; for(register int i=1;i<=tot;i++){ sort(b+l[i],b+r[i]+1); } return; } void change(int x,int y,int k) { if(belong[x]==belong[y]){ for(register int i=x;i<=y;i++){ a[i]+=k; } for(register int i=l[belong[x]];i<=r[belong[x]];i++){ b[i]=a[i]; } sort(b+l[belong[x]],b+r[belong[x]]+1); return ; } for(register int i=x;i<=r[belong[x]];i++){ a[i]+=k; } for(register int i=l[belong[x]];i<=r[belong[x]];i++){ b[i]=a[i]; } sort(b+l[belong[x]],b+r[belong[x]]+1); for(register int i=l[belong[y]];i<=y;i++){ a[i]+=k; } for(register int i=l[belong[y]];i<=r[belong[y]];i++){ b[i]=a[i]; } sort(b+l[belong[y]],b+r[belong[y]]+1); for(register int i=belong[x]+1;i<=belong[y]-1;i++){ lazy[i]+=k; } } int query(int x,int y,int goal) { int ans=0; if(belong[x]==belong[y]){ for(register int i=x;i<=y;i++){ if(a[i]+lazy[belong[x]]>=goal) ++ans; } return ans; } for(register int i=x;i<=r[belong[x]];i++){ if(a[i]+lazy[belong[x]]>=goal) ++ans; } for(register int i=l[belong[y]];i<=y;i++){ if(a[i]+lazy[belong[y]]>=goal) ++ans; } for(register int i=belong[x]+1;i<=belong[y]-1;i++){ int L=l[i],R=r[i],mid; while(L<R){ int mid=(L+R)/2; if(b[mid]+lazy[i]>=goal){ R=mid; } else{ L=mid+1; } } if(L==r[i]){ ans+=((b[L]+lazy[i])>=goal); continue; } ans+=(r[i]-L+1); } return ans; } int main() { cin>>n>>m; for(register int i=1;i<=n;i++) scanf("%d",&a[i]); build(); for(register int i=1;i<=m;i++){ char type; int x,y,k; cin>>type>>x>>y>>k; if(type=='M'){ change(x,y,k); } else{ cout<<query(x,y,k)<<endl; } } }
众人皆醉我独醒,举世皆浊我独清