BZOJ 3343 教主的魔法 分块
mdzz....我的-Wall怕不是被吃了。。。快读里面==写成了=。。。。艹。。。调了一中午、、、QWQ我的时间啊。。。
分块:块内排序加tag(就是偏移量),来二分比所求大的位置;散块暴力修改。。。
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #define R register int using namespace std; inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } int n,m,q,T; int a[1000010],s[1000010],pos[1000010],tg[1000010]; inline void build(int p) { R l=(p-1)*T+1,r=min(p*T,n); for(R i=l;i<=r;++i) s[i]=a[i]; sort(s+l,s+r+1); } inline int calc(int p,int d) { R l=(p-1)*T+1,r=min(p*T,n); R tmp=lower_bound(s+l,s+r+1,d)-s-1; return r-tmp; } inline void update(int l,int r,int d) { if(pos[l]==pos[r]) for(R i=l;i<=r;++i) a[i]+=d; else { for(R i=l;i<=pos[l]*T;++i) a[i]+=d; for(R i=(pos[r]-1)*T+1;i<=r;++i) a[i]+=d; } pos[l]==pos[r]?build(pos[l]):build(pos[l]),build(pos[r]); for(R i=pos[l]+1;i<pos[r];++i) tg[i]+=d; } inline int query(int l,int r,int d) { R ret=0; if(pos[l]==pos[r]) {for(R i=l;i<=r;++i) if(a[i]+tg[pos[i]]>=d) ++ret;} else { for(R i=l;i<=pos[l]*T;++i) if(a[i]+tg[pos[i]]>=d) ++ret; for(R i=(pos[r]-1)*T+1;i<=r;++i) if(a[i]+tg[pos[i]]>=d) ++ret; } for(R i=pos[l]+1;i<pos[r];++i) ret+=calc(i,d-tg[i]); return ret; } signed main() { n=g(),q=g(); T=1000; for(R i=1;i<=n;++i) s[i]=a[i]=g(); for(R i=1;i<=n;++i) pos[i]=(i-1)/T+1; if(n%T) m=n/T+1; else m=n/T; for(R i=1;i<=m;++i) build(i); for(R i=1;i<=q;++i) { register char ch; while(!isalpha(ch=getchar())); R l=g(),r=g(),d=g(); if(ch=='M') update(l,r,d); else printf("%d\n",query(l,r,d)); } }
f我再也不能写错快读了。。。2019.04.23