bzoj1503: [NOI2004]郁闷的出纳员(伸展树)

1503: [NOI2004]郁闷的出纳员

题目:传送门 

 


 

 

题解:

   修改操作一共不超过100

   直接暴力在伸展树上修改

    


 

 

代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<cmath>
  5 #include<algorithm>
  6 using namespace std;
  7 struct node
  8 {
  9     int d,c,n,f,son[2];
 10 }tr[110000];int len,root,ans;
 11 void add(int d,int f)
 12 {
 13     len++;tr[len].d=d;tr[len].n=tr[len].c=1;
 14     tr[len].son[0]=tr[len].son[1]=0;tr[len].f=f;
 15     if(d<tr[f].d)tr[f].son[0]=len;
 16     else          tr[f].son[1]=len;
 17 }
 18 void update(int x)
 19 {
 20     int lc=tr[x].son[0],rc=tr[x].son[1];
 21     tr[x].c=tr[lc].c+tr[rc].c+tr[x].n;
 22 }
 23 int findip(int d)
 24 {
 25     int x=root;
 26     while(tr[x].d!=d)
 27     {
 28         if(d<tr[x].d)
 29         {
 30             if(tr[x].son[0]==0)break;
 31             else x=tr[x].son[0];
 32         }
 33         else
 34         {
 35             if(tr[x].son[1]==0)break;
 36             else x=tr[x].son[1];
 37         }
 38     }
 39     return x;
 40 }
 41 void rotate(int x,int w)
 42 {
 43     int f=tr[x].f,ff=tr[f].f;
 44     int r,R;
 45     r=tr[x].son[w],R=f;
 46     tr[R].son[1-w]=r;
 47     if(r!=0)tr[r].f=R;
 48     
 49     r=x,R=ff;
 50     if(tr[R].son[0]==f)tr[R].son[0]=r;
 51     else                tr[R].son[1]=r;
 52     tr[r].f=R;
 53     
 54     r=f,R=x;
 55     tr[R].son[w]=r;
 56     tr[r].f=R;
 57     
 58     update(f);update(x);
 59 }
 60 void splay(int x,int rt)
 61 {
 62     while(tr[x].f!=rt)
 63     {
 64         int f=tr[x].f,ff=tr[f].f;
 65         if(ff==rt)
 66         {
 67             if(tr[f].son[0]==x)rotate(x,1);
 68             else                  rotate(x,0);
 69         }
 70         else
 71         {
 72                  if(tr[ff].son[0]==f && tr[f].son[0]==x)rotate(f,1),rotate(x,1);
 73             else if(tr[ff].son[1]==f && tr[f].son[1]==x)rotate(f,0),rotate(x,0);
 74             else if(tr[ff].son[1]==f && tr[f].son[0]==x)rotate(x,1),rotate(x,0);
 75             else if(tr[ff].son[0]==f && tr[f].son[1]==x)rotate(x,0),rotate(x,1);
 76         }
 77     }
 78     if(rt==0)root=x;
 79 }
 80 void ins(int d)
 81 {
 82     if(root==0)
 83     {
 84         add(d,0);root=len;
 85         return ;
 86     }
 87     int x=findip(d);
 88     if(tr[x].d==d)
 89     {
 90         tr[x].n++;
 91         update(x);
 92         splay(x,0);
 93     }
 94     else
 95     {
 96         add(d,x);
 97         update(x);
 98         splay(len,0);
 99     }
100 }
101 void del(int d)
102 {
103     int x=findip(d);if(tr[x].d!=d)return ;
104     ans+=tr[x].n;splay(x,0);
105     if(tr[x].son[0]==0 && tr[x].son[1]==0){root=0;len=0;}
106     else if(tr[x].son[0]!=0 && tr[x].son[1]==0){root=tr[x].son[0];tr[root].f=0;}
107     else if(tr[x].son[0]==0 && tr[x].son[1]!=0){root=tr[x].son[1];tr[root].f=0;}
108     else
109     {
110         int p=tr[x].son[0];
111         while(tr[p].son[1]!=0)p=tr[p].son[1];
112         splay(p,x);
113         
114         int r=tr[x].son[1],R=p;
115         tr[R].son[1]=r;
116         tr[r].f=R;
117         
118         root=p;tr[root].f=0;
119         update(root);
120     }
121 }
122 void findshuzi(int k)
123 {
124     int x=root;
125     while(1)
126     {
127         int lc=tr[x].son[0],rc=tr[x].son[1];
128         if(k<=tr[lc].c)x=lc;
129         else if(k>tr[lc].c+tr[x].n)k-=tr[lc].c+tr[x].n,x=rc;
130         else break;
131     }
132     printf("%d\n",tr[x].d);
133 }
134 int n,m,sum,sc[110000];
135 void jia(int x,int k)
136 {
137     tr[x].d+=k;
138     if(tr[x].son[0]!=0)jia(tr[x].son[0],k);
139     if(tr[x].son[1]!=0)jia(tr[x].son[1],k);
140 }
141 void jian(int x,int k)
142 {
143     tr[x].d-=k;if(tr[x].d<m)sc[++sum]=x;
144     if(tr[x].son[0]!=0)jian(tr[x].son[0],k);
145     if(tr[x].son[1]!=0)jian(tr[x].son[1],k);
146 }
147 char st[2];
148 int main()
149 {
150     scanf("%d%d",&n,&m);ans=0;
151     len=0;root=0;
152     for(int i=1;i<=n;i++)
153     {
154         sum=0;
155         int x;scanf("%s%d",st+1,&x);
156         if(st[1]=='I')
157         {
158             if(x<m)continue;
159             ins(x);
160         }
161         else if(st[1]=='A')jia(root,x);
162         else if(st[1]=='S')
163         {
164             jian(root,x);
165             for(int j=1;j<=sum;j++)del(tr[sc[j]].d);
166         }
167         else 
168         {
169             if(tr[root].c<x)printf("-1\n");
170             else findshuzi(tr[root].c-x+1);
171         }
172     }
173     printf("%d\n",ans);
174     return 0;
175 }

 

posted @ 2018-04-11 16:30  CHerish_OI  阅读(236)  评论(0编辑  收藏  举报