BZOJ 1269 [AHOI2006]文本编辑器editor

来源:互联网 发布:淘宝加绒外套女短 编辑:程序博客网 时间:2024/06/17 12:54

这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器。你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义: 文本:由0个或多个字符构成的序列。这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格。光标:在一段文本中用于指示位置的标记,可以位于文本的第一个字符之前,文本的最后一个字符之后或文本的某两个相邻字符之间。文本编辑器:为一个可以对一段文本和该文本中的一个光标进行如下七条操作的程序。如果这段文本为空,我们就说这个文本编辑器是空的。 编写一个程序: 建立一个空的文本编辑器。 从输入文件中读入一些操作指令并执行。 对所有执行过的GET操作,将指定的内容写入输出文件。
这里写图片描述这里写图片描述


【题目分析】
Splay维护区间,但是加入了一些玄学元素。


【代码】(自己代码太丑了,贴一个学长的代码)

#include<iostream>#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<algorithm>#define F(i,j,n) for(int i=j;i<=n;i++)#define D(i,j,n) for(int i=j;i>=n;i--)#define LL long long#define pa pair<int,int>#define MAXN 2100000#define INF 1000000000#define key c[c[rt][1]][0]using namespace std;int pos=1,rt=0,tot=0,n,x,c[MAXN][2],s[MAXN],fa[MAXN];char v[MAXN],op[10],ch[MAXN];bool rev[MAXN];inline void pushup(int k){    if (!k) return;    s[k]=s[c[k][0]]+s[c[k][1]]+1;}inline void update(int k){    if (!k) return;    rev[k]^=1;    swap(c[k][0],c[k][1]);}inline void pushdown(int k){    if (!k) return;    if (rev[k])    {        update(c[k][0]);update(c[k][1]);        rev[k]=0;    }}inline void rotate(int x,int &k){    int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1;    if (y==k) k=x;    else c[z][c[z][1]==y]=x;    fa[x]=z;fa[y]=x;fa[c[x][r]]=y;    c[y][l]=c[x][r];c[x][r]=y;    pushup(y);pushup(x);}inline void splay(int x,int &k){    while (x!=k)    {        int y=fa[x],z=fa[y];        if (y!=k)        {            if ((c[y][0]==x)^(c[z][0]==y)) rotate(x,k);            else rotate(y,k);        }        rotate(x,k);    }}inline int find(int k,int rank){    pushdown(k);    int l=c[k][0],r=c[k][1];    if (s[l]+1==rank) return k;    else if (s[l]>=rank) return find(l,rank);    else return find(r,rank-s[l]-1);}inline void split(int l,int r){    int x=find(rt,l-1),y=find(rt,r+1);    splay(x,rt);splay(y,c[rt][1]);}inline void newnode(int &k,char ch,int last){    k=++tot;    fa[k]=last;    v[k]=ch;    c[k][0]=c[k][1]=rev[k]=0;    s[k]=1;}inline void ins(int &k,int l,int r,int last){    int mid=(l+r)>>1;    newnode(k,ch[mid],last);    if (l<mid) ins(c[k][0],l,mid-1,k);    if (mid<r) ins(c[k][1],mid+1,r,k);    pushup(k);}inline void solveins(){    scanf("%d%*c",&x);    gets(ch);    split(pos+1,pos);    ins(key,0,x-1,c[rt][1]);    pushup(c[rt][1]);pushup(rt);}inline void solvedel(){    scanf("%d%*c",&x);    split(pos+1,pos+x);    fa[key]=0;key=0;    pushup(c[rt][1]);pushup(rt);}inline void solverev(){    scanf("%d%*c",&x);    split(pos+1,pos+x);    update(key);}int main(){    newnode(rt,'*',0);newnode(c[rt][1],'*',rt);pushup(rt);    scanf("%d%*c",&n);    F(i,1,n)    {        scanf("%s%*c",op);        if (op[0]=='M') {scanf("%d%*c",&x);pos=x+1;}        else if (op[0]=='I') solveins();        else if (op[0]=='D') solvedel();        else if (op[0]=='R') solverev();        else if (op[0]=='G') printf("%c\n",v[find(rt,pos+1)]);        else if (op[0]=='P') pos--;        else pos++;    }}
0 0
原创粉丝点击