[bzoj1269][AHOI2006]文本编辑器editor

题面不kuai了,这是链接
额,学习一下指针板子,因为输入\(10^6\)个字符,所以不能再用维修数列那题回收的非指针了。。。不爽
只好成为指(te)针(pan)党了
顺便链接一下
看网上说可能会越界,判断一下。。。
输出一个字符可以用后继实现,但搞的时候要下传标记。。毁我1天啊
还有删除时坠吼释放内存空间,最后释放所有空间,听说会炸,没试过
还有加了个null(不是NULL),size设为0,就不用特判了
因为第一个操作一定是Insert,所以先读入然后维护,也不用特判了

// It is made by XZZ
#include<cstdio>
#include<algorithm>
#define pr pair<point,point>
#define mp make_pair
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
typedef long long ll;
il int gi(){
    rg int x=0,f=1;rg char ch=getchar();
    while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int seed=19260817;
il int Rand(){return seed=seed*48271ll%2147483647;}
typedef struct node* point;
point null;
struct node{
    char data;
    int size,rand;
    point ls,rs;
    bool rev;
    node(char ch){data=ch,size=1,rand=Rand(),rev=0,ls=rs=null;}
    il vd down(){if(rev)rev=0,ls->rev^=1,rs->rev^=1,swap(ls,rs);}
    il vd reset(){if(ls!=null)ls->down();if(rs!=null)rs->down();size=ls->size+rs->size+1;}
};
point root=null;
il point build(int n){
    point stack[n+1];
    int top=0;
    char ch;
    rep(i,1,n){
	ch=getchar();while(ch=='\n')ch=getchar();
	point now=new node(ch),lst=null;
	while(top&&stack[top]->rand>now->rand)lst=stack[top],stack[top--]->reset();
	now->ls=lst;if(top)stack[top]->rs=now;stack[++top]=now;
    }
    while(top)stack[top--]->reset();
    return stack[1];
}
il point merge(point a,point b){
    if(a==null)return b;
    if(b==null)return a;
    if(a->rand<b->rand){a->down(),a->rs=merge(a->rs,b),a->reset();return a;}
    else {b->down(),b->ls=merge(a,b->ls),b->reset();return b;}
}
il pr split(point now,int num){
    if(now==null)return mp(null,null);
    now->down();
    point ls=now->ls,rs=now->rs;
    if(num==ls->size){now->ls=null,now->reset();return mp(ls,now);}
    if(num==ls->size+1){now->rs=null,now->reset();return mp(now,rs);}
    if(num<ls->size){pr T=split(ls,num);now->ls=T.second,now->reset();return mp(T.first,now);}
    pr T=split(rs,num-ls->size-1);now->rs=T.first,now->reset();return mp(now,T.second);
}
il vd del(point now){if(now!=null)del(now->ls),del(now->rs),delete now;}
int main(){
    int m=gi()-1,pos=0;
    char opt[10];
    null=new node('%');
    null->size=0;
    {
	scanf("%*s");
	root=build(gi());
    }
    while(m--){
	scanf("%s",opt);
	if(opt[0]=='M')pos=max(0,min(gi(),root->size));
	else if(opt[0]=='P'){if(pos)--pos;}
	else if(opt[0]=='N'){if(pos!=root->size)++pos;}
	else if(opt[0]=='G'){
	    pr T=split(root,pos);
	    char lst;point now=T.second;
	    while(now!=null)lst=now->data,now->down(),now=now->ls;
	    printf("%c\n",lst);
	    root=merge(T.first,T.second);
	}
	else if(opt[0]=='I'){
	    pr T=split(root,pos);
	    root=merge(T.first,merge(build(gi()),T.second));
	}
	else{
	    pr T=split(root,pos),TT=split(T.second,gi());
	    if(opt[0]=='D')root=merge(T.first,TT.second),del(TT.first);
	    else TT.first->rev^=1,root=merge(T.first,merge(TT.first,TT.second));
	}
    }
    del(root);
    delete null;
    return 0;
}

没了

posted @ 2017-08-09 13:27  菜狗xzz  阅读(448)  评论(0编辑  收藏  举报