填坑 bzoj3337
算是个板子题吧,就是不知道啥时候能写出来。
#include<cstring> #include<iostream> #include<cctype> #include<cstdio> #include<algorithm> #include<queue> #include<cmath> #define writ(x,c) write(x),putchar(c); typedef long long ll; const int N=10000,MAX=1<<29; using namespace std; inline int read() { char c;int x=0;bool f=0; for(;!isdigit(c);c=getchar()) if(c=='-') f=1; for(;isdigit(c);c=getchar()) x=(x<<1)+(x<<3)+(c^48); return (f ? -x : x); } template <class _T> void write(_T x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } int n,m,size; struct node { int d[1003],s[1003],rev,add,same,size,next; ll sum; }a[N]; queue<int> q; void Init() { } int new_node() { int temp=q.front();q.pop(); return temp; } void clear(int x){a[x].rev=a[x].add=a[x].same=a[x].size=a[x].rev=0;} void erase(int x){q.push(x);clear(x);} void find(int &pos,int &now) { for(now=0;a[now].next!=-1&&pos>a[now].size;now=a[now].next) pos-=a[now].size; } void down(int now) { int tot=a[now].size; if(a[now].rev) { a[now].rev=false; int tt=(tot>>1); for(int u=1;u<=tt;u++) swap(a[now].d[u],a[now].d[tot-u+1]); } if(a[now].same!=0) { for(int u=1;u<=tot;u++) a[now].d[u]=a[now].same; a[now].sum=a[now].same*tot,a[now].same=0; } if(a[now].add!=0) { for(int u=1;u<=tot;u++) a[now].d[u]+=a[now].add; a[now].sum=a[now].sum+a[now].add*tot,a[now].add=0; } } void update(int x) { a[x].sum=0; for(int u=1;u<=a[x].size;u++) a[x].sum+=a[x].d[u],a[x].s[u]=a[x].d[u]; sort(a[x].s+1,a[x].s+a[x].size+1); } void spilt(int now,int pos) { down(now); int t=new_node(); for(int u=pos;u<=a[now].size;u++) a[t].d[++a[t].size]=a[now].d[u]; a[t].next=a[now].next,a[now].next=t,a[now].size=max(pos-1,0); update(t);update(now); } void Merge(int now) { int k=a[now].next; down(now);down(k); for(int u=1;u<=a[k].size;u++) a[now].d[++a[now].size]=a[k].d[u]; a[now].next=a[k].next;erase(k); update(now); } void maintain(int now) { for(;now!=-1;now=a[now].next) if(a[now].next!=-1&&a[now].size+a[a[now].next].size<=size) Merge(now); } void ins(int pos,int x) { int now;pos++; find(pos,now);spilt(now,pos); a[now].d[++a[now].size]=x,a[now].sum+=x; int lalal; for(lalal=1;lalal<a[now].size;lalal++) if(a[now].s[lalal]>x) break; for(int u=a[now].size;u>lalal;u--) a[now].s[u]=a[now].s[u-1]; a[now].s[lalal]=x; maintain(now); } void del(int pos) { int now; find(pos,now);down(now); for(int u=pos+1;u<=a[now].size;u++) a[now].d[u-1]=a[now].d[u]; a[now].size--; update(now);maintain(now); } void solve(int l,int r,int &lp,int &rp) { int pos=l; find(pos,lp);spilt(lp,pos); pos=r+1; find(pos,rp);spilt(rp,pos); pos=r; find(pos,rp); } int st[N]; void rverse(int l,int r) { int lp,rp; solve(l,r,lp,rp); int now=lp,top=0; for(int u=a[lp].next;u!=a[rp].next;u=a[u].next) st[++top]=u,a[u].rev^=1; a[st[1]].next=a[rp].next; for(int u=top;u>1;u--) a[st[u]].next=st[u-1]; a[lp].next=rp; maintain(lp); } void slip(int l,int r,int k) { int lp,mp,rp,np; solve(l,r-k,lp,mp),solve(r-k+1,r,mp,rp); np=a[lp].next,a[lp].next=a[mp].next,a[mp].next=a[rp].next,a[rp].next=np; maintain(lp); } void add(int l,int r,int val) { int lp,rp; solve(l,r,lp,rp); for(int now=a[lp].next;now!=a[rp].next;now=a[now].next) a[now].add+=val,a[now].sum=a[now].sum+a[now].size*val; maintain(lp); } void same(int l,int r,int val) { int lp,rp; solve(l,r,lp,rp); for(int now=a[lp].next;now!=a[rp].next;now=a[now].next) a[now].add=0,a[now].same=val,a[now].sum=a[now].size*val; maintain(lp); } ll getsum(int l,int r) { int lp,rp; solve(l,r,lp,rp); ll ans=0; for(int now=a[lp].next;now!=a[rp].next;now=a[now].next) ans=ans+a[now].sum; maintain(lp); return ans; } int getcha(int l,int r) { int lp,rp; solve(l,r,lp,rp); int maxx=-MAX,minn=MAX; for(int now=a[lp].next;now!=a[rp].next;now=a[now].next) if(a[now].size!=0) if(a[now].same!=0) minn=min(minn,a[now].same+a[now].add), maxx=max(maxx,a[now].same+a[now].add); else minn=min(minn,a[now].s[1]+a[now].add), maxx=max(maxx,a[now].s[a[now].size]+a[now].add); maintain(lp); return maxx-minn; } int near(int l,int r,int val) { int lp,rp; solve(l,r,lp,rp); int ans=MAX; for(int now=a[lp].next;now!=a[rp].next;now=a[now].next) { if(a[now].same) ans=min(ans,abs(val-a[now].same-a[now].add)); else { int id=lower_bound(a[now].s+1,a[now].s+a[now].size+1,val-a[now].add)-a[now].s; if(id!=a[now].size+1) ans=min(ans,a[now].s[id]+a[now].add-val); if(id!=1) id--,ans=min(ans,val-a[now].s[id]-a[now].add); } } maintain(lp); return ans; } int rank(int l,int r,int k) { int lp,rp; solve(l,r,lp,rp); int ll=0,rr=MAX; while(ll<rr) { int mid=(ll+rr)/2+1,sum=1; for(int now=a[lp].next;now!=a[rp].next;now=a[now].next) { if(a[now].same!=0) { if(a[now].same+a[now].add<mid) sum=sum+a[now].size; } else { int id=upper_bound(a[now].s+1,a[now].s+a[now].size+1,mid-a[now].add-1)-a[now].s; sum=sum+max(0,id-1); } } if(k>=sum) ll=mid; else rr=mid-1; } maintain(lp); return ll; } int sec(int l,int r,int val) { int lp,rp; solve(l,r,lp,rp); int ans=0; for(int now=a[lp].next;now!=a[rp].next;now=a[now].next) { if(a[now].same!=0) { if(a[now].same+a[now].add<val) ans=ans+a[now].size; } else { int it=upper_bound(a[now].s+1,a[now].s+a[now].size+1,val-a[now].add-1)-a[now].s; ans=ans+it-1; } } maintain(lp); return ans; } int main() { n=read(),size=sqrt(n); for(int i=1;i<N;i++) q.push(i);a[0].next=-1;a[0].size=0; for(int u=1;u<=n;u++) { int x=read();ins(u-1,x); } m=read(); while(m--) { register int op,x,y,z;op=read(); switch(op) { case 1:x=read();y=read();ins(x,y);break; case 2:x=read();del(x);break; case 3:x=read();y=read();rverse(x,y);break; case 4:x=read();y=read();z=read();slip(x,y,z);break; case 5:x=read();y=read();z=read();add(x,y,z);break; case 6:x=read();y=read();z=read();same(x,y,z);break; case 7:x=read();y=read();writ(getsum(x,y),'\n');break; case 8:x=read();y=read();writ(getcha(x,y),'\n');break; case 9:x=read();y=read();z=read();writ(near(x,y,z),'\n');break; case 10:x=read();y=read();z=read();writ(rank(x,y,z),'\n');break; case 11:x=read();y=read();z=read();writ(sec(x,y,z),'\n');break; } } return 0; }
忘开longlong,忘用逆元,忘删调试信息,瞬间爆炸