题目链接:http://acm.nankai.edu.cn/p1248.html
题目思路:splay,需要用到up函数。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<queue>
#include<algorithm>
#include<vector>
#include<stack>
#include<list>
#include<iostream>
#include<map>
using namespace std;
#define inf 0x3f3f3f3f
#define M 200000
#define keytree (ch[ch[root][1]][0])
int max(int a,int b)
{
return a>b?a:b;
}
int min(int a,int b)
{
return a<b?a:b;
}
int p[M],ch[M][2],s[M],v[M];
int root,n,m,level,change,top1;
/*void debug(int x)
{
printf("x %d p %d ch0 %d ch1 %d s %d\n",x,p[x],ch[x][0],ch[x][1],s[x]);
if(ch[x][0])
debug(ch[x][0]);
if(ch[x][1])
debug(ch[x][1]);
}*/
void newnode(int &x,int val,int pre)
{
x=++top1;
ch[x][0]=ch[x][1]=0;
s[x]=1;
v[x]=val;
p[x]=pre;
}
void init()
{
top1=0;
p[0]=ch[0][0]=ch[0][1]=s[0]=v[0]=0;
change=0;
newnode(root,-inf,0);
newnode(ch[root][1],inf,root);
s[root]=2;
}
void up(int x)
{
if(!x)return;
int l=ch[x][0],r=ch[x][1];
s[x]=s[l]+1+s[r];
}
void rot(int x,int f)
{
int y=p[x];
ch[y][!f]=ch[x][f];
p[ch[x][f]]=y;
p[x]=p[y];
ch[p[y]][ch[p[y]][1]==y]=x;
p[y]=x;
ch[x][f]=y;
up(y);
}
void splay(int x,int goal)
{
while(p[x]!=goal)
{
if(p[p[x]]==goal) rot(x,ch[p[x]][0]==x);
else
{
int y=p[x],f=ch[p[y]][0]==y;
if(ch[y][f]==x)
{
rot(x,!f);
}
else
rot(y,f);
rot(x,f);
}
}
up(x);
if(goal==0)
root=x;
}
int suc(int val)
{
int x=root;
int tmp;
while(x)
{
if(v[x]==val)
return x;
if(v[x]>val)
tmp=x;
x=ch[x][v[x]<val];
}
return tmp;
}
void insert(int val)
{
int x=root;
while(ch[x][v[x]<val])
{
x=ch[x][v[x]<val];
}
newnode(ch[x][v[x]<val],val,x);
splay(ch[x][v[x]<val],0);
}
void del()
{
splay(1,0);
if(suc(level-change)==1)
return;
splay(suc(level-change),root);
keytree=0;
up(ch[root][1]);
up(root);
}
int search(int k)
{
int x=root;
while(s[ch[x][1]]!=k)
{
if(s[ch[x][1]]>k)
x=ch[x][1];
else
{
k=k-s[ch[x][1]]-1;
x=ch[x][0];
}
}
return v[x];
}
int main()
{
char op[4];
int k;
int num=0;
while(scanf("%d%d",&n,&level)!=EOF)
{
init();
while(n--)
{
scanf("%s%d",op,&k);
if(op[0]=='I')
{
if(k>=level)
{
insert(k-change);
num++;
}
}
if(op[0]=='A')
{
change+=k;
}
if(op[0]=='S')
{
change-=k;
del();
}
if(op[0]=='F')
{
if(s[root]-2<k)
{
printf("-1\n");
continue;
}
printf("%d\n",search(k)+change);
}
}
printf("%d\n",num-s[root]+2);
}
}
本文详细介绍了使用Splay树解决特定问题的算法实现过程。通过插入、删除等操作,Splay树能够保持良好的平衡状态,进而高效地进行查找。文章提供了完整的C++代码示例,包括初始化、旋转、上溯等关键函数。
523

被折叠的 条评论
为什么被折叠?



