[NOI2004]郁闷的出纳员

时间:2019-10-09
本文章向大家介绍[NOI2004]郁闷的出纳员,主要包括[NOI2004]郁闷的出纳员使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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 }

原文地址:https://www.cnblogs.com/zhenglw/p/11644261.html