Poj 2887-Big String Splay

时间:2023-03-09 13:09:15
Poj 2887-Big String  Splay
Big String
Time Limit: 1000MS   Memory Limit: 131072K
Total Submissions: 6527   Accepted: 1563

Description

You are given a string and supposed to do some string manipulations.

Input

The first line of the input contains the initial string. You can assume that it is non-empty and its length does not exceed 1,000,000.

The second line contains the number of manipulation commands N (0 < N ≤ 2,000). The following N lines describe a command each. The commands are in one of the two formats below:

  1. I ch p: Insert a character ch before the p-th character of the current string. If p is larger than the length of the string, the character is appended to the end of the string.
  2. Q p: Query the p-th character of the current string. The input ensures that the p-th character exists.

All characters in the input are digits or lowercase letters of the English alphabet.

Output

For each Q command output one line containing only the single character queried.

Sample Input

ab
7
Q 1
I c 2
I d 4
I e 2
Q 5
I f 1
Q 3

Sample Output

a
d
e

Source

题意:给一个字符串,要求查询某一位的字母,或在某一位前插入一个字母.

题解:

Splay的单点插入,和单点查询.

记得内存大小要把操作的2000加上。

速度422ms,还不错。。。

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 1002010
struct node
{
int left,right,size;
char val;
}tree[MAXN];
int father[MAXN];
char str[MAXN];
void Pushup(int k)
{
tree[k].size=tree[tree[k].left].size+tree[tree[k].right].size+;
}
void rotate(int x,int &root)
{
int y=father[x],z=father[y];
if(y==root)root=x;
else
{
if(tree[z].left==y)tree[z].left=x;
else tree[z].right=x;
}
if(tree[y].left==x)
{
father[x]=z;father[y]=x;tree[y].left=tree[x].right;tree[x].right=y;father[tree[y].left]=y;
}
else
{
father[x]=z;father[y]=x;tree[y].right=tree[x].left;tree[x].left=y;father[tree[y].right]=y;
}
Pushup(y);Pushup(x);
}
void Splay(int x,int &root)
{
while(x!=root)
{
int y=father[x],z=father[y];
if(y!=root)
{
if((tree[y].left==x)^(tree[z].left==y))rotate(x,root);
else rotate(y,root);
}
rotate(x,root);
}
}
void Build(int l,int r,int f)
{
if(l>r)return;
int now=l,fa=f;
if(l==r)
{
tree[now].val=str[l];tree[now].size=;
father[now]=fa;
if(l<f)tree[fa].left=now;
else tree[fa].right=now;
return;
}
int mid=(l+r)/;
now=mid;
Build(l,mid-,mid);Build(mid+,r,mid);
tree[now].val=str[mid];father[now]=fa;
Pushup(now);
if(mid<f)tree[fa].left=now;
else tree[fa].right=now;
}
int Find(int root,int rank)
{
if(rank==tree[tree[root].left].size+)return root;
if(rank<=tree[tree[root].left].size)return Find(tree[root].left,rank);
else return Find(tree[root].right,rank-tree[tree[root].left].size-);
}
int main()
{
int m,i,k,L,R,x,y,z,lstr,rt,n;
char ch,fh[];
scanf("%s",str+);
lstr=strlen(str+);
m=lstr+;
Build(,m,);
rt=(+m)/;
scanf("%d",&n);
for(i=;i<=n;i++)
{
scanf("\n%s",fh);
if(fh[]=='Q')
{
scanf("%d",&k);
L=k;R=k+;
x=Find(rt,L);y=Find(rt,R);
Splay(x,rt);Splay(y,tree[x].right);
z=tree[y].left;
printf("%c\n",tree[z].val);
}
else
{
scanf("\n%c %d",&ch,&k);
L=k;R=k+;
x=Find(rt,L);y=Find(rt,R);
Splay(x,rt);Splay(y,tree[x].right);
tree[y].left=++m;
z=tree[y].left;tree[z].size=;
father[z]=y;tree[z].val=ch;
Pushup(y);Pushup(x);
}
}
return ;
}