[NOI2004]郁闷的出纳员
由于我打起Splay来太容易出锅了...所以前几天学了FHQ—Treap
这道题就可以用FHQ-Treap水过...!!
这题确实可以通过增量的方法做...(然而我WA了)
后来一气之下写了一个大常数的直接每次操作Push_Down一下维护节点val和lazy_tag
Insert操作就是裸的操作
对于A S 操作我们就用打lazy_tag的方法维护一下节点权值,然后能下传的地方就下传,之后把小于min的点删掉(直接不要)就好了
对于F操作就是普通的查询排名(这里也记得Push_Down)
虽然常数大了一些,但是暴力都能跑过的题目...这样做还是绰绰有余的la~
1 #include<bits/stdc++.h> 2 #define writeln(x) write(x),puts("") 3 #define writep(x) write(x),putchar(' ') 4 using namespace std; 5 inline int read(){ 6 int ans=0,f=1;char chr=getchar(); 7 while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();} 8 while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();} 9 return ans*f; 10 }void write(int x){ 11 if(x<0) putchar('-'),x=-x; 12 if(x>9) write(x/10); 13 putchar(x%10+'0'); 14 }const int M = 2e5+5; 15 int cnt,n,m,noww,minn,root,x,y,z,tot; 16 struct P{int val,key,sz,l,r,lz;}s[M]; 17 inline void Push_Up(int x){s[x].sz=s[s[x].l].sz+s[s[x].r].sz+1;} 18 inline void Push_Down(int x){ 19 if(!s[x].lz)return; 20 s[s[x].l].lz+=s[x].lz; 21 s[s[x].r].lz+=s[x].lz; 22 s[s[x].l].val+=s[x].lz; 23 s[s[x].r].val+=s[x].lz; 24 s[x].lz=0; 25 }inline int NewNode(int val){ 26 s[++cnt]=(P){val,rand(),1,0,0,0}; 27 return cnt; 28 }inline void Split(int now,int val,int &x,int &y){ 29 if(!now)return x=y=0,void(); 30 Push_Down(now); 31 if(s[now].val<=val)x=now,Split(s[now].r,val,s[now].r,y); 32 else y=now,Split(s[now].l,val,x,s[now].l); 33 Push_Up(now); 34 }inline int Merge(int x,int y){ 35 if(!x||!y)return (x+y); 36 if(s[x].key<s[y].key){ 37 Push_Down(x); 38 s[x].r=Merge(s[x].r,y); 39 Push_Up(x);return x; 40 }Push_Down(y),s[y].l=Merge(x,s[y].l); 41 Push_Up(y);return y; 42 }inline void Insert(int val){ 43 if(val<m)return; 44 Split(root,val,x,y); 45 root=Merge(Merge(x,NewNode(val)),y); 46 }inline void Delete(){ 47 Split(root,m-1,x,y); 48 tot+=s[x].sz; 49 root=y; 50 }inline void Rank(int rk){ 51 if(rk>s[root].sz) return puts("-1"),void(); 52 int now=root; 53 while(now){ 54 Push_Down(now); 55 if(rk==s[s[now].r].sz+1)break; 56 if(rk>s[s[now].r].sz)rk-=s[s[now].r].sz+1,now=s[now].l; 57 else now=s[now].r; 58 }printf("%d\n",s[now].val); 59 }inline void Add(int val){ 60 s[root].val+=val;s[root].lz+=val; 61 Delete(); 62 }int main(){ 63 srand(unsigned(time(0))); 64 n=read(),m=read();char op[2]; 65 while(n--){ 66 scanf("%s",op+1);x=read(); 67 if(op[1]=='I')Insert(x); 68 if(op[1]=='S')Add(-x); 69 if(op[1]=='A')Add(x); 70 if(op[1]=='F')Rank(x); 71 }cout<<tot<<endl; 72 return 0; 73 }