【转载】poj2761(平衡树:Splay)

经典题目
注意要离线做(在线算法想了半天都想不出)
便练了Splay
  1 #include<cstdio>
  2 #include<algorithm>
  3 using namespace std;
  4 
  5 const int MAX=100001+10;
  6 const int NUM=50001+10;
  7 int n,m;
  8 
  9 int pretty[MAX];
 10 
 11 struct node
 12 {
 13     int w;
 14     int ch[2],p;
 15 }tree[MAX];
 16 int cnt,root,size[MAX];
 17 bool del[MAX];
 18 
 19 void newspl()
 20 {
 21     size[0]=0;
 22     tree[0].w=tree[0].p=tree[0].ch[0]=tree[0].ch[1]=0;
 23     root=cnt=0;
 24     return;
 25 }
 26 
 27 void newnode()
 28 {
 29     ++cnt;
 30     tree[cnt].w=tree[cnt].ch[0]=tree[cnt].ch[1]=tree[cnt].p=0;
 31     del[cnt]=0;
 32 }
 33 
 34 void link(int u,int v,int T)
 35 {
 36     tree[u].p=v;
 37     tree[v].ch[T]=u;
 38 }
 39 
 40 void tree_print(int now)
 41 {
 42     if(!now)return;
 43     tree_print(tree[now].ch[0]);
 44     printf("%d\n",tree[now].w);
 45     tree_print(tree[now].ch[1]);
 46 }
 47 
 48 void update(int u)
 49 {
 50     size[u]=size[tree[u].ch[0]]+size[tree[u].ch[1]]+1;
 51     return;
 52 }
 53 
 54 void rotate(int u,int T)
 55 {
 56     int fa=tree[u].p;
 57     int gfa=tree[fa].p;
 58     tree[tree[u].ch[T]].p=fa;
 59     tree[fa].ch[T^1]=tree[u].ch[T];
 60     tree[fa].p=u;
 61     tree[u].ch[T]=fa;
 62     if(tree[gfa].ch[0]==fa) tree[gfa].ch[0]=u;
 63     else tree[gfa].ch[1]=u;
 64     tree[u].p=gfa;
 65     update(fa);update(u);
 66 }
 67 
 68 void Splay(int u,int goal)
 69 {
 70     int fa,gfa,T,H;
 71     while(!(tree[u].p==goal))
 72     {
 73         fa=tree[u].p;gfa=tree[fa].p;
 74         if(gfa==goal)rotate(u,tree[fa].ch[0]==u);
 75         else
 76         {
 77             T=(tree[gfa].ch[0]==fa);
 78             H=(tree[fa].ch[0]==u);
 79             if(T==H){rotate(fa,T);rotate(u,H);}
 80             else{rotate(u,H);rotate(u,T);}
 81         }
 82     }
 83     if(goal==0)root=u;
 84     update(u);
 85 }
 86 
 87 void insert(int w)
 88 {
 89     int now=root,T;
 90     while(1)
 91     {
 92         T=tree[now].w<w;
 93         if(tree[now].ch[T])
 94             now=tree[now].ch[T];
 95         else 
 96         {
 97             newnode();
 98             tree[cnt].w=w;
 99             tree[cnt].p=now;
100             tree[now].ch[T]=cnt;
101             Splay(cnt,0);
102             return;
103         }
104     }
105 }
106 
107 int succ()
108 {
109     int now=tree[root].ch[0];
110     while(1)
111     {
112         if(tree[now].ch[1])
113             now=tree[now].ch[1];
114         else return now;
115     }
116 }
117 
118 void delect(int w)
119 {
120     int now=root,T,y;
121     while(1)
122     {
123         if(!now){printf("no\n");return;}
124         if(tree[now].w==w)break;
125         else
126         { 
127             T=tree[now].w<w;
128             now=tree[now].ch[T];
129         }
130     }
131     del[now]=1;
132     Splay(now,0);
133     if(!tree[now].ch[0]&&!tree[now].ch[1])root=0;
134     else if(!tree[now].ch[0])
135     {
136         root=tree[now].ch[1];
137         tree[tree[now].ch[1]].p=0;
138     }else 
139     {
140         y=succ();
141         Splay(y,now);
142         link(tree[now].ch[1],y,1);
143         root=y;tree[y].p=0;
144         update(y);
145     }
146 }
147 
148 struct seg
149 {
150     int x,y,k,num;
151 }q[NUM];
152 
153 int cmp(const seg& a,const seg& b)
154 {
155     if(a.x!=b.x)return a.x<b.x;
156     else return a.y<b.y;
157 }
158 
159 int ask(int k)
160 {
161     int now=root;
162     while(1)
163     {
164         if(k==size[tree[now].ch[0]]+1)return tree[now].w;
165         else if(k<=size[tree[now].ch[0]])now=tree[now].ch[0];
166         else 
167         {
168             k-=size[tree[now].ch[0]]+1;
169             now=tree[now].ch[1];
170         }
171     }
172 }
173 
174 int answer[NUM];
175 
176 int main()
177 {
178 #ifndef ONLINE_JUDGE
179     freopen("input.in","r",stdin);freopen("ouput.out","w",stdout);
180 #endif
181     int i,j;
182     scanf("%d %d",&n,&m);
183     for(i=1;i<=n;++i)scanf("%d",&pretty[i]);
184     for(i=1;i<=m;++i)
185     {
186         scanf("%d %d %d",&q[i].x,&q[i].y,&q[i].k);
187         q[i].num=i;
188     }
189     sort(q+1,q+m+1,cmp);
190     for(i=1;i<=m;++i)
191     {
192         if(q[i].x>q[i-1].y)
193         {
194             newspl();
195             for(j=q[i].x;j<=q[i].y;++j)
196             {
197                 insert(pretty[j]);
198             }
199         }else
200         {
201             for(j=q[i-1].x;j<q[i].x;++j)delect(pretty[j]);
202             for(j=q[i-1].y+1;j<=q[i].y;++j)insert(pretty[j]);
203         }
204         answer[q[i].num]=ask(q[i].k);
205     }
206     for(i=1;i<=m;++i)
207         printf("%d\n",answer[i]);
208     return 0;
209 }

 

 
 

posted on 2012-07-20 10:39  青色有角三倍速  阅读(313)  评论(0)    收藏  举报