题目还是牛耳杯程序设计大赛的D题,之前已经描述过,就不在赘述了。
之前用AVL实现的,这里附上一个用SBT实现的版本,对比发现SBT实现更为简单,而且时空消耗略少。
搓长丑的SBT代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<memory.h>
#include<ctime>
using namespace std;
const int MAXN = 100010;
struct KEY
{
int wgt;
int num;
KEY(int w=0,int n=0):wgt(w),num(n){}
bool operator == (const KEY &k) const
{
return wgt==k.wgt&&num==k.num;
}
bool operator < (const KEY &k) const
{
if(wgt!=k.wgt)return wgt<k.wgt;
return num<k.num;
}
};
struct SBT
{
int l[MAXN],r[MAXN],size[MAXN],pool[MAXN],ROOT,TOP,NODE;
KEY Key[MAXN];
void init()
{
TOP = NODE = ROOT = 0;
}
int newnode(int w,int n)
{
int node;
if(TOP)node = pool[TOP--];
else node = ++NODE;
Key[node].wgt = w;
Key[node].num = n;
size[node] = 1;
l[node] = r[node] = 0;
return node;
}
void delnode(int x)
{
pool[++TOP] = x;
Key[x].wgt = Key[x].num = size[x] = l[x] = r[x] = 0;
}
void left_rotate(int &p)
{
int x = r[p];
r[p] = l[x];
l[x] = p;
size[p] = size[l[p]]+size[r[p]]+1;
size[x] = size[l[x]]+size[r[x]]+1;
p = x;
}
void right_rotate(int &p)
{
int x = l[p];
l[p] = r[x];
r[x] = p;
size[p] = size[l[p]]+size[r[p]]+1;
size[x] = size[l[x]]+size[r[x]]+1;
p = x;
}
void Maintain(int &p)
{
if(size[l[l[p]]]>size[r[p]])
{
right_rotate(p);
Maintain(r[p]);
Maintain(p);
}
if(size[r[l[p]]]>size[r[p]])
{
left_rotate(l[p]);
right_rotate(p);
Maintain(l[p]);
Maintain(r[p]);
Maintain(p);
}
if(size[r[r[p]]]>size[l[p]])
{
left_rotate(p);
Maintain(l[p]);
Maintain(p);
}
if(size[l[r[p]]]>size[l[p]])
{
right_rotate(r[p]);
left_rotate(p);
Maintain(r[p]);
Maintain(l[p]);
Maintain(p);
}
}
void Maintain_faster(int &p,bool flag)
{
if(flag==0)
{
if(size[l[l[p]]]>size[r[p]])right_rotate(p);
else if(size[r[l[p]]]>size[r[p]])
{
left_rotate(l[p]);
right_rotate(p);
}
else return ;
}
else
{
if(size[r[r[p]]]>size[l[p]])left_rotate(p);
else if(size[l[r[p]]]>size[l[p]])
{
right_rotate(r[p]);
left_rotate(p);
}
else return;
}
Maintain_faster(l[p],0);
Maintain_faster(r[p],1);
Maintain_faster(p,1);
Maintain_faster(p,0);
}
void insert(int &p,KEY k)
{
if(!p)
{
p = newnode(k.wgt,k.num);
return;
}
if(k<Key[p])insert(l[p],k);
else insert(r[p],k);
size[p]=size[l[p]]+size[r[p]]+1;
Maintain_faster(p,!(k<Key[p]));
}
int findmin(int p)
{
if(l[p])return findmin(l[p]);
else return p;
}
void remove(int &p,KEY k)
{
if(p)
{
if(k==Key[p])
{
if(!l[p])
{
int x = p;
p = r[p];
delnode(x);
}
else if(!r[p])
{
int x = p;
p = l[p];
delnode(x);
}
else
{
int x = findmin(r[p]);
Key[p] = Key[x];
remove(r[p],Key[x]);
}
}
else if(k<Key[p])remove(l[p],k);
else remove(r[p],k);
if(p){
size[p] = size[l[p]]+size[r[p]]+1;
}
//Maintain(p);
}
}
int Select(int p,int k)
{
int rank = size[l[p]]+1;
if(rank==k)return p;
else if(rank<k)return Select(r[p],k-rank);
return Select(l[p],k);
}
void print(int p)
{
if(!p)return;
print(l[p]);
printf("%d\n",size[p]);
print(r[p]);
}
}sbt;
int A[MAXN];
int main()
{
clock_t start,final;
start = clock();
int n,m;
freopen("D.in","r",stdin);
freopen("Dans.out","w",stdout);
while(scanf("%d%d",&n,&m)!=EOF)
{
sbt.init();
for(int i=1;i<=n;i++)scanf("%d",&A[i]);
for(int i=1;i<=n;i++)sbt.insert(sbt.ROOT,KEY(A[i],i));
for(int i=0;i<m;i++)
{
int x,y;char op[5];
scanf("%s",op);
//sbt.print(sbt.ROOT);
if(op[0]=='A')
{
scanf("%d%d",&x,&y);
sbt.remove(sbt.ROOT,KEY(A[x],x));
A[x]+=y;
sbt.insert(sbt.ROOT,KEY(A[x],x));
}
else if(op[0]=='B')
{
scanf("%d%d",&x,&y);
sbt.remove(sbt.ROOT,KEY(A[x],x));
A[x]-=y;
sbt.insert(sbt.ROOT,KEY(A[x],x));
}
else if(op[0]=='C')
{
scanf("%d%d",&x,&y);
sbt.remove(sbt.ROOT,KEY(A[x],x));sbt.remove(sbt.ROOT,KEY(A[y],y));
A[y]+=A[x];
sbt.insert(sbt.ROOT,KEY(A[y],y));
}
else
{
scanf("%d",&x);
printf("%d\n",sbt.Key[sbt.Select(sbt.ROOT,x)].wgt);
}
}
}
final = clock();
printf("Time is %lf\n",(double)(final-start)/CLOCKS_PER_SEC);
return 0;
}