1507: [NOI2003]Editor

Description

Input

输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作。其中: 为了使输入文件便于阅读,Insert操作的字符串中可能会插入一些回车符,请忽略掉它们(如果难以理解这句话,可以参考样例)。 除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。 这里我们有如下假定:  MOVE操作不超过50000个,INSERT和DELETE操作的总个数不超过4000,PREV和NEXT操作的总个数不超过200000。  所有INSERT插入的字符数之和不超过2M(1M=1024*1024),正确的输出文件长度不超过3M字节。  DELETE操作和GET操作执行时光标后必然有足够的字符。MOVE、PREV、NEXT操作必然不会试图把光标移动到非法位置。  输入文件没有错误。 对C++选手的提示:经测试,最大的测试数据使用fstream进行输入有可能会比使用stdio慢约1秒。

Output

输出文件editor.out的每行依次对应输入文件中每条GET指令的输出。

Sample Input

15
Insert 26
abcdefghijklmnop
qrstuv wxy
Move 15
Delete 11
Move 5
Insert 1
^
Next
Insert 1
_
Next
Next
Insert 4
.\/.
Get 4
Prev
Insert 1
^
Move 0
Get 22

Sample Output

.\/.
abcde^_^f.\/.ghijklmno
 
用splay维护区间,对于光标,定义pos对应即可,插入的话将pos旋转到根,再把pos后面的那个值旋转到pos的右儿子,因为我们是按权值建立splay,所以这时pos的右儿子是没有左儿子的,
我们直接在它的左儿子中插入即可,删除就将pos旋转到根,再把pos后第k+1个旋转到它的右儿子,那么pos右儿子的左儿子大小刚好为k,我们直接删除左子树即可,
输出直接中序遍历递归输出即可。
可是。。。为什么我的程序过不去QAQ,感觉没有问题啊。。。。。
  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <cstdlib>
  6 #define maxn 1024*1024*3
  7 using namespace std;
  8 int cnt,root,pos,tot=0,q,k;
  9 struct splay
 10 {
 11     int l,r,size,fa;
 12     char data;
 13 }a[maxn];
 14 char str[maxn];
 15 void Push_up(int x)
 16 {
 17     a[x].size=1+a[a[x].l].size+a[a[x].r].size;
 18 }
 19 void zig(int x)
 20 {
 21     int y=a[x].fa;
 22     int z=a[y].fa;
 23     a[y].fa=x,a[x].fa=z;
 24     a[y].l=a[x].r,a[a[x].r].fa=y,a[x].r=y;
 25     if (a[z].l==y) a[z].l=x;
 26     else a[z].r=x;
 27     Push_up(y);
 28 }
 29 void zag(int x)
 30 {
 31     int y=a[x].fa;
 32     int z=a[y].fa;
 33     a[y].fa=x,a[x].fa=z;
 34     a[y].r=a[x].l,a[a[x].l].fa=y,a[x].l=y;
 35     if (y==a[z].l) a[z].l=x;
 36     else a[z].r=x;
 37     Push_up(y);
 38 }
 39 void splay(int x,int s)
 40 {
 41     while (a[x].fa!=s)
 42     {
 43         int y=a[x].fa;
 44         int z=a[y].fa;
 45         if (z==s)
 46         {
 47             if (x==a[y].l) zig(x);
 48             else zag(x);
 49         }
 50         else
 51         {
 52             if (y==a[z].l)
 53             {
 54                 if (x==a[y].l) zig(y),zig(x);
 55                 else zag(x),zig(x);
 56             }
 57             else
 58             {
 59                 if (x==a[y].r) zag(y),zag(x);
 60                 else zig(x),zag(x);
 61             }
 62         }
 63     }
 64     Push_up(x);
 65     if (s==0) root=x;
 66 }
 67 int Findkth(int x,int k)
 68 {
 69     int s=a[a[x].l].size;
 70     if (k==s+1) return x;
 71     if (k<=s) return Findkth(a[x].l,k);
 72     return Findkth(a[x].r,k-s-1);
 73 }
 74 int Getmin(int x)
 75 {
 76     while (a[x].l)
 77         x=a[x].l;
 78     return x;
 79 }
 80 void New_Node(int &x,int fa,char c)
 81 {
 82     x=++tot;
 83     a[x].fa=fa;
 84     a[x].l=a[x].r=a[x].size=0;
 85     a[x].data=c;
 86 }
 87 void Build(int &x,int fa,int l,int r,char *str)
 88 {
 89     if (l>r) return;
 90     int m=(l+r)>>1;
 91     New_Node(x,fa,str[m]);
 92     Build(a[x].l,x,l,m-1,str);
 93     Build(a[x].r,x,m+1,r,str);
 94     Push_up(x);
 95 }
 96 void Insert(char *str,int l)
 97 {
 98     int x=Findkth(root,pos);
 99     splay(x,0);
100     x=Getmin(a[root].r);
101     splay(x,root);
102     Build(a[x].l,x,0,l-1,str);
103 }
104 void Delet(int k)
105 {
106     int x=Findkth(root,pos);
107     splay(x,0);
108     x=Findkth(root,pos+k+1);
109     splay(x,root);
110     a[a[x].l].fa=0;
111     a[x].l=0;
112     Push_up(x);
113     Push_up(root);
114 }
115 void dg(int x,int k)
116 {
117     if (!a[x].r&&!a[x].l)
118     {
119         cnt++;
120         if (cnt>k) return;
121         printf("%c",a[x].data);
122         return;
123     }
124     if (a[x].l) dg(a[x].l,k);
125     cnt++;
126     if (cnt>k) return;
127     printf("%c",a[x].data);
128     if (a[x].r) dg(a[x].r,k);
129 }
130 void Print(int k)
131 {
132     int x=Findkth(root,pos);
133     splay(x,0);
134     cnt=0;
135     dg(a[root].r,k);
136     printf("\n");
137 }
138 int main()
139 {
140     //freopen("input.txt","r",stdin);
141     scanf("%d",&q);
142     root=tot=0;
143     pos=1;
144     Build(root,0,0,1,"  ");
145     while (q--)
146     {
147         scanf("%s",str);
148         if (str[0]=='I')
149         {
150             scanf("%d",&k);
151             getchar();
152             for (int i=0;i<k;i++)
153             {
154                 str[i]=getchar();
155                 if (str[i]=='\n') {i--;continue;}
156             }
157             Insert(str,k);
158         }
159         else if (str[0]=='M')
160         {
161             scanf("%d",&k);
162             pos=k+1;
163         }
164         else if (str[0]=='D')
165         {
166             scanf("%d",&k);
167             Delet(k);
168         }
169         else if (str[0]=='P')
170             pos--;
171         else if (str[0]=='N')
172             pos++;
173         else
174         {
175             scanf("%d",&k);
176             Print(k);
177         }
178     }
179     return 0;
180 }
正确姿势
  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<algorithm>
  7 #include<string>
  8 #include<map>
  9 #include<queue>
 10 #include<vector>
 11 #include<set>
 12 #define inf 1000000000
 13 #define maxn 1024*1024*3
 14 #define maxm 10000+5
 15 #define eps 1e-10
 16 #define ll long long
 17 #define for0(i,n) for(int i=0;i<=(n);i++)
 18 #define for1(i,n) for(int i=1;i<=(n);i++)
 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 22 using namespace std;
 23 int read(){
 24     int x=0,f=1;char ch=getchar();
 25     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 26     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 27     return x*f;
 28 }
 29 int cnt,rt,pos=1,tot,q;
 30 int c[maxn][2],s[maxn],fa[maxn];
 31 char w[maxn],s1[maxn];
 32 void pushup(int x){
 33     s[x]=s[c[x][1]]+s[c[x][0]]+1;
 34 }
 35 void rotate(int x,int &k){
 36     int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1;
 37     if(y==k)k=x;
 38     else c[z][(c[z][1]==y)]=x;
 39     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
 40     c[y][l]=c[x][r];c[x][r]=y;
 41     pushup(y);pushup(x);
 42 }
 43 void splay(int x,int &k){
 44     while(x!=k){
 45         int y=fa[x],z=fa[y];
 46         if(y!=k){
 47             if(c[y][0]==x^c[z][0]==y)rotate(x,k);
 48             else rotate(x,k);
 49         }
 50         else rotate(x,k);
 51     }
 52 }
 53 int find(int x,int k){
 54     if(k==s[c[x][0]]+1)return x;
 55     if(k<=s[c[x][0]])return find(c[x][0],k);
 56     else return find(c[x][1],k-s[c[x][0]]-1);
 57 }
 58 int mi(int x){
 59     while(c[x][0])
 60         x=c[x][0];
 61     return x;
 62 }
 63 void build(int &x,int f,int l,int r,char *s1){
 64     if(l>r)return ;
 65     int mid=(l+r)>>1;
 66     x=++tot;c[x][0]=c[x][1]=s[x]=0;
 67     w[x]=s1[mid];fa[x]=f;
 68     build(c[x][0],x,l,mid-1,s1);build(c[x][1],x,mid+1,r,s1);
 69     pushup(x);
 70 }
 71 void insert(char *s1,int l){
 72     int x=find(rt,pos);
 73     splay(x,rt);
 74     x=mi(c[rt][1]);
 75     splay(x,c[rt][1]);
 76     build(c[x][0],x,0,l-1,s1);
 77 }
 78 void del(int k){
 79     int x=find(rt,pos);
 80     splay(x,rt);
 81     pushup(rt);
 82     x=find(rt,pos+k+1);
 83     splay(x,c[rt][1]);
 84     fa[c[x][0]]=0;c[x][0]=0;
 85     pushup(x);pushup(rt);
 86 }
 87 void print(int x,int k){
 88     if(!c[x][1]&&!c[x][1]){
 89         cnt++;
 90         if(cnt>k)return ;
 91         printf("%c",w[x]);
 92         return ;
 93     }
 94     if(c[x][0])print(c[x][0],k);
 95     cnt++;
 96     if(cnt>k)return ;
 97     printf("%c",w[x]);
 98     if(c[x][1])print(c[x][1],k);
 99 }
100 void get(int k){
101     int x=find(rt,pos);
102     splay(x,rt);
103     cnt=0;
104     print(c[x][1],k);
105     printf("\n");
106 }
107 int main(){
108     //freopen("input.txt","r",stdin);
109     //freopen("output.txt","w",stdout);
110     q=read();
111     build(rt,0,0,1," ");
112     while(q--){
113         char tmp=getchar();
114         while(tmp!='I'&&tmp!='M'&&tmp!='D'&&tmp!='P'&&tmp!='N'&&tmp!='G')tmp=getchar();
115         if(tmp=='I'){
116             int k=read();
117             for0(i,k-1){
118                 char ch=getchar();
119                 while(ch<32||ch>126)ch=getchar();
120                 s1[i]=ch;
121             }
122             insert(s1,k);
123         }
124         else if(tmp=='M'){
125             int k=read();
126             pos=k+1;
127         }
128         else if(tmp=='D'){
129             int k=read();
130             del(k);
131         }
132         else if(tmp=='P')pos--;
133         else if(tmp=='N')pos++;
134         else{
135             int k=read();
136             get(k);
137         }
138     }
139     return 0;
140 }
错误姿势QAQ

 

转载于:https://www.cnblogs.com/htwx/articles/5651407.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值