[题解]luogu_P1486郁闷的出纳员(权值线段树
作者:互联网
一眼权值线段树因为不会写平衡树线段树还好写啊
然后死咗
才发现后来的人不会被前面操作影响
于是维护一个历史记录,每次插入的时候减去delta因为查询出来要加上delta,常用操作
然而调了一万年
#include<bits/stdc++.h> #define ls (x<<1) #define rs (x<<1|1) #define mid ((l+r)>>1) using namespace std; const int maxm=400009; const int base=200000; int n,m,lmt,ans,delta; int t[maxm<<2],tg[maxm<<2]; inline void pd(int x){ if(tg[x]){ tg[ls]=tg[rs]=1; t[ls]=t[rs]=0; tg[x]=0; } } void insert(int x,int l,int r,int pos){ // if(pos==200080)cout<<l<<' '<<r<<endl; if(l==r){ t[x]++; return; } pd(x); if(pos<=mid)insert(ls,l,mid,pos); else insert(rs,mid+1,r,pos); t[x]=t[ls]+t[rs]; } void del(int x,int l,int r,int L,int R){ if(L<=l&&r<=R){ ans+=t[x]; t[x]=0;tg[x]=1; // cout<<'$'<<l<<' '<<r<<endl; return; } pd(x); if(L<=mid)del(ls,l,mid,L,R); if(R>mid)del(rs,mid+1,r,L,R); t[x]=t[ls]+t[rs]; } int query(int x,int l,int r,int k){ if(l==r)return l; pd(x); if(k>t[rs])return query(ls,l,mid,k-t[rs]); else return query(rs,mid+1,r,k); } int main(){ scanf("%d%d",&n,&lmt);char s[5]; for(int i=1,k;i<=n;i++){ scanf("%s",s); scanf("%d",&k); if(s[0]=='I'){ if(k>=lmt)insert(1,0,400000,k-delta+base); } else if(s[0]=='A'){ // lmt-=k; delta+=k; } else if(s[0]=='S'){ // lmt+=k; delta-=k; // cout<<'#'<<lmt<<endl; del(1,1,400000,0,lmt-1-delta+base); // cout<<'#'<<t[1]<<endl; } else{ if(k>t[1])printf("-1\n"); else printf("%d\n",query(1,1,400000,k)+delta-base); } } printf("%d",ans); }
标签:P1486,rs,int,题解,luogu,lmt,else,delta,query 来源: https://www.cnblogs.com/superminivan/p/11592235.html