文本编辑器
要求写一个数据结构,支持区间删除、区间插入,区间查询。这不是平衡树是什么。
坑点有点多。首先空格也会被当成是一种文本输入并存储,调试的时候我一度认为是哪里出bug了(data一栏是……啥都没有?|)。还有就是数组要开大一点,不知道为什么要开到2e6。然后就是在做区间插入的时候最好把插入的序列按最平衡的状态建好直接拼到原树上,这样不仅插入部分少了一个log,还使得整棵树更加平衡了。好开森。
40分钟。
加了个区间翻转变成了另一道题,但真不觉得这种鬼玩意有什么做的必要。区间翻转是好的,但搞这种输入游戏有意思吗。link
code:
//begin at 8:40
#include<bits/stdc++.h>
//#define zczc
using namespace std;
const int N=2000010;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
inline int op(){
char w[10];scanf("%s",w);
switch(w[0]){
case 'M':return 1;break;
case 'I':return 2;break;
case 'D':return 3;break;
case 'G':return 4;break;
case 'P':return 5;break;
case 'N':return 6;break;
}
}
inline char get(){
char w=getchar();
while(w<32||w>126)w=getchar();
return w;
}
int m,n;
char w[N];
#define lc t[x].ch[0]
#define rc t[x].ch[1]
struct node{
int f,ch[2],size;
char data;
}t[N];
int cnt,root;
inline void pushup(int x){
t[x].size=t[lc].size+t[rc].size+1;
}
inline int build(int l,int r,int fa){
if(l>r)return 0;
int x=++cnt;int mid=l+r+1>>1;
t[x].f=fa,t[x].size=1,t[x].data=w[mid];
if(l==r)return x;
lc=build(l,mid-1,x);rc=build(mid+1,r,x);
pushup(x);return x;
}
inline void rotate(int x){
int y=t[x].f;int z=t[y].f;
int kk=t[y].ch[1]==x;int cd=t[x].ch[kk^1];
if(z)t[z].ch[t[z].ch[1]==y]=x;t[x].f=z;
t[y].ch[kk]=cd;t[cd].f=y;
t[x].ch[kk^1]=y;t[y].f=x;
pushup(y);pushup(x);
if(y==root)root=x;return;
}
inline void splay(int x,int rt){
while(t[x].f^rt){
int y=t[x].f;int z=t[y].f;
if(z^rt)(t[z].ch[1]==y)^(t[y].ch[1]==x)?rotate(x):rotate(y);
rotate(x);
}
if(rt==0)root=x;
}
inline int find(int x,int kk){
if(t[lc].size>=kk)return find(lc,kk);
if(t[lc].size+1==kk)return x;
return find(rc,kk-t[lc].size-1);
}
inline void out(int x){
if(!x)return;
out(lc);putchar(t[x].data);out(rc);
}
int rrr;
inline void print(int x){
if(!x)return;
printf("%d %c %d %d&%d %d\n",x,t[x].data,t[x].size,lc,rc,t[x].f);
print(lc);print(rc);
}
#undef lc
#undef rc
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
root=1;cnt=2;
t[1].size=2,t[2].size=1;
t[1].ch[1]=2;t[2].f=1;
t[1].data=t[2].data='|';
read(m);
int p=1,s1,s2;
for(int ii=1;ii<=m;ii++){
switch(op()){
case 1:read(n);p=n+1;break;
case 2:
read(n);for(int i=1;i<=n;i++)w[i]=get();
s1=find(root,p),s2=find(root,p+1);
splay(s1,0);splay(s2,s1);
t[s2].ch[0]=build(1,n,s2);pushup(s2);pushup(s1);break;
case 3:
read(n);s1=find(root,p),s2=find(root,p+n+1);
splay(s1,0);splay(s2,s1);t[s2].ch[0]=0;
pushup(s2);pushup(s1);break;
case 4:
read(n);s1=find(root,p);s2=find(root,p+n+1);
splay(s1,0);splay(s2,s1);
out(t[s2].ch[0]);putchar('\n');break;
case 5:p--;break;
case 6:p++;break;
}
}
return 0;
}
//finish at 9:20
一如既往,万事胜意