码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 4441 Queue Sequence(splay)

时间:2017-01-31 20:53:55      阅读:279      评论:0      收藏:0      [点我收藏+]

标签:div   ++   hid   pid   sed   com   break   lld   scanf   

题目链接:hdu 4441 Queue Sequence

这题看了题解写的,题解传送门

技术分享
  1 #include<bits/stdc++.h>
  2 #define F(i,a,b) for(int i=a;i<=b;++i)
  3 #define ls l,m,rt<<1
  4 #define rs m+1,r,rt<<1|1
  5 using namespace std;
  6 typedef long long ll;
  7 
  8 const int N=1e6+7;
  9 int _t;
 10 int pos[N][2];
 11 int tr[N<<2],q,cas;
 12 
 13 struct Splay_tree
 14 {
 15     int root;
 16     int key[N],cnt[N][2],sz[N],f[N],ch[N][2];
 17     ll sum[N];
 18     inline void nw(int &x,int val,int fa)
 19     {
 20         x=++_t,key[x]=val,f[x]=fa,sz[x]=1;
 21         sum[x]=val;
 22         cnt[x][0]=val>0;
 23         cnt[x][1]=val<0;
 24         ch[x][0]=ch[x][1]=0;
 25     }
 26     inline void up(int x){
 27         if(!x)return;
 28         int l=ch[x][0],r=ch[x][1];
 29         sz[x]=sz[l]+sz[r]+1;
 30         cnt[x][0]=cnt[l][0]+cnt[r][0]+(key[x]>0);
 31         cnt[x][1]=cnt[l][1]+cnt[r][1]+(key[x]<0);
 32         sum[x]=sum[l]+sum[r]+key[x];
 33     }
 34     void init()
 35     {
 36         root=0,_t=0;
 37         key[0]=0,cnt[0][1]=cnt[0][0]=0,f[0]=0,sz[0]=0,sum[0]=0;
 38         nw(root,0,0);
 39         nw(ch[root][1],q+1,root);
 40         up(ch[root][1]);
 41         up(root);
 42     }
 43     void rotate(int x){
 44         int y=f[x],w=ch[y][1]==x;
 45         ch[y][w]=ch[x][w^1];
 46         if(ch[x][w^1])f[ch[x][w^1]]=y;
 47         if(f[y]){
 48             int z=f[y];
 49             if(ch[z][0]==y)ch[z][0]=x;
 50             if(ch[z][1]==y)ch[z][1]=x;
 51         }
 52         f[x]=f[y],ch[x][w^1]=y,f[y]=x,up(y);
 53     }
 54     void splay(int x,int w){
 55         int s=1,i=x,y;
 56         while(f[x]!=w){
 57             y=f[x];
 58             if(f[y]!=w){if((ch[f[y]][0]==y)^(ch[y][0]==x))rotate(x);else rotate(y);}
 59             rotate(x);
 60         }
 61         if(!w)root=x;
 62         up(x);
 63     }
 64     inline int kth(int k)//获得第k小
 65     {
 66         if(k>sz[root]||k<=0)return 0;
 67         int x=root,tmp;
 68         while(1)
 69         {
 70             tmp=sz[ch[x][0]]+1;
 71             if(k==tmp)break;
 72             if(k<tmp)x=ch[x][0];else k-=tmp,x=ch[x][1];
 73         }
 74         return x;
 75     }
 76     inline int find(int x,int n)
 77     {
 78         int l=ch[x][0],r=ch[x][1];
 79         if(cnt[l][1]==n&&key[x]<0){splay(x,0);return sz[ch[root][0]];}
 80         else if(cnt[l][1]>=n+1)return find(l,n);
 81         else return find(r,n-cnt[l][1]-(key[x]<0));
 82     }
 83     inline void Delete(int r){  
 84         splay(r,0);  
 85         int pos=sz[ch[r][0]];
 86         splay(kth(pos),0);
 87         splay(kth(pos+2),root);
 88         ch[ch[root][1]][0]=0;  
 89         up(ch[root][1]);  
 90         up(root);  
 91     } 
 92     int ins(int x,int p)
 93     {
 94         int ps=kth(p);
 95         splay(ps,0);
 96         splay(kth(p+1),root);
 97         nw(ch[ch[root][1]][0],x,ch[root][1]);
 98         up(ch[root][1]),up(root);
 99         return ch[ch[root][1]][0];
100     }
101 }spt;
102 //--------------------------------
103 void build(int l=1,int r=q,int rt=1)
104 {
105     if(l==r){tr[rt]=l;return;}
106     int m=l+r>>1;
107     build(ls),build(rs);
108     tr[rt]=min(tr[rt<<1],tr[rt<<1|1]);
109 }
110 
111 void update(int x,int v,int l=1,int r=q,int rt=1)//1为插入
112 {
113     if(l==r)
114     {
115         if(v)tr[rt]=INT_MAX;else tr[rt]=l;
116         return;
117     }
118     int m=l+r>>1;
119     if(x<=m)update(x,v,ls);else update(x,v,rs);
120     tr[rt]=min(tr[rt<<1],tr[rt<<1|1]);
121 }
122 
123 void insert(int x)
124 {
125     int now=tr[1];
126     update(now,1);
127     pos[now][0]=spt.ins(now,x+1);
128     spt.splay(pos[now][0],0);
129     int n=spt.cnt[spt.ch[spt.root][0]][0],m;
130     if(spt.cnt[spt.root][1]<=n)m=spt.sz[spt.root]-1;
131     else m=spt.find(spt.root,n);
132     pos[now][1]=spt.ins(-now,m);
133 }
134 
135 void query(int x)
136 {
137     spt.splay(pos[x][0],0);
138     spt.splay(pos[x][1],spt.root);
139     printf("%lld\n",spt.sum[spt.ch[spt.ch[spt.root][1]][0]]);
140 }
141 
142 void remove(int x)
143 {
144     spt.Delete(pos[x][0]);
145     spt.Delete(pos[x][1]);
146     update(x,0);
147 }
148 
149 int main()
150 {
151     while(~scanf("%d",&q))
152     {
153         char cmd[10];
154         int x;
155         printf("Case #%d:\n",++cas);
156         spt.init(),build();
157         F(i,1,q)
158         {
159             scanf("%s%d",cmd,&x);
160             if(cmd[0]==i)insert(x);
161             else if(cmd[0]==q)query(x);
162             else remove(x);
163         }
164     }
165     return 0;
166 }
View Code

 

hdu 4441 Queue Sequence(splay)

标签:div   ++   hid   pid   sed   com   break   lld   scanf   

原文地址:http://www.cnblogs.com/bin-gege/p/6359071.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!