【BZOJ2223】【COCI2009】PATULJCI
【BZOJ1269】【AHOI2006】文本编辑器editor

【BZOJ1507】【NOI2003】Editor

Zarxdy34 posted @ 2016年3月13日 18:46 in BZOJ with tags Splay rope , 696 阅读

  Splay,敲完就好了。

  坑爹的换行符竟然是不读入的...

 

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=3000010;

struct Splay_Tree
{
	struct Node
	{
		Node *c[2],*p;
		char v;
		int tag_rev;
		int size;
		int w() {return this==p->c[1];}
	}MEM[maxn],*Null,*root;
	int IDs;

	#define ls x->c[0]
	#define rs x->c[1]

	Node* NewNode()
	{
		Node *x=&MEM[IDs++];
		ls=rs=x->p=Null;
		x->v=0;x->size=1;
		return x;
	}

	Splay_Tree()
	{
		Null=&MEM[0];
		Null->v=Null->size=0;
		Null->c[0]=Null->c[1]=Null->p=Null;
		IDs=1;
		Node *LeftNull=NewNode();
		Node *RightNull=NewNode();
		root=LeftNull;
		root->c[1]=RightNull;RightNull->p=root;root->size=2;
	}

	void Update(Node *x) {if (x==Null) return;x->size=ls->size+rs->size+1;}

	void Mark_Rev(Node *x) {swap(ls,rs);x->tag_rev^=1;}

	void Push_Down(Node *x)
	{
		if (x==Null) return;
		if (x->tag_rev)
		{
			Mark_Rev(ls);
			Mark_Rev(rs);
			x->tag_rev=0;
		}
	}

	void Rotate(Node *x)
	{
		Node *p=x->p;
		int w=x->w();
		Push_Down(p);Push_Down(x);
		if (p==root) root=x;
		x->p=p->p;p->p->c[p->w()]=x;
		x->c[!w]->p=p;p->c[w]=x->c[!w];
		x->c[!w]=p;p->p=x;
		Update(p);
	}

	void Splay(Node *x,Node *top)
	{
		if (x==Null) return;
		Push_Down(x);
		while (x->p!=top)
		{
			if (x->p->p==top) {Rotate(x);break;}
			if (x->w()==x->p->w()) Rotate(x->p),Rotate(x);
			else Rotate(x),Rotate(x);
		}
		Update(x);
	}

	Node* Select(int k)
	{
		Node *x=root;
		while (k)
		{
			Push_Down(x);
			int lsz=ls->size;
			if (lsz+1==k) return x;
			else if (lsz>=k) x=ls;
			else k-=lsz+1,x=rs;
		}
	}

	Node* Build_Tree(int l,int r,char *ch)
	{
		Node *x=NewNode();
		if (l==r) {x->v=ch[l];return x;}
		int mid=(l+r)>>1;
		x->v=ch[mid];
		if (l<mid) ls=Build_Tree(l,mid-1,ch);
		if (mid<r) rs=Build_Tree(mid+1,r,ch);
		ls->p=rs->p=x;
		Update(x);
		return x;
	}

	Node* Get_Seq(int l,int r)
	{
		Splay(Select(l-1),Null);
		Splay(Select(r+1),root);
		return root->c[1]->c[0];
	}

	void Print(Node *x)
	{
		if (x==Null) return;
		Print(ls);
		putchar(x->v);
		Print(rs);
	}
	
	void Insert(int pos,int n,char *ch)
	{
		Node *NewRoot=Build_Tree(1,n,ch);
		Splay(Select(pos),Null);
		Splay(Select(pos+1),root);
		root->c[1]->c[0]=NewRoot;
		NewRoot->p=root->c[1];
		Splay(NewRoot,Null);
	}
	
	void Delete(int pos,int n)
	{
		Node *x=Get_Seq(pos+1,pos+n);
		x->p->c[x->w()]=Null;
		Update(x->p);
		Splay(x->p,Null);
	}
	
	void Rotate(int pos,int n)
	{
		Node *x=Get_Seq(pos+1,pos+n);
		Mark_Rev(x);
		Splay(x,Null);
	}

	void Print(int pos,int n)
	{
		Node *x=Get_Seq(pos+1,pos+n);
		Print(x);
		Splay(x,Null);
	}
}T;

char readchar() {char ch;while ((ch=getchar())<32 || ch>126 || ch=='\n');return ch;}

char inst[maxn];

int main()
{
	int TT,pos=0,n;
	scanf("%d",&TT);
	while (TT--)
	{
		char ctr[10];
		scanf("%s",ctr);
		if (ctr[0]=='M') scanf("%d",&n),pos=n;
		else if (ctr[0]=='I')
		{
			scanf("%d",&n);
			for (int i=1;i<=n;i++) inst[i]=readchar();
			T.Insert(pos+1,n,inst);
		}
		else if (ctr[0]=='D') scanf("%d",&n),T.Delete(pos+1,n);
		else if (ctr[0]=='G') scanf("%d",&n),T.Print(pos+1,n),putchar('\n');
		else if (ctr[0]=='P') pos--;
		else if (ctr[0]=='N') pos++;
		else if (ctr[0]=='R') scanf("%d",&n),T.Rotate(pos+1,n);
	}
	return 0;
}

 

  听说一个rope就好了,我就写了一下。

 

#include <cstdio>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
const int maxn=3000010;

char readchar() {char ch;while ((ch=getchar())<32 || ch>126 || ch=='\n');return ch;}

char ch[maxn];
char ctr[20];
crope text;

int main()
{
	int T;
	scanf("%d",&T);
	int pos=0,n;
	while (T--)
	{
		scanf("%s",ctr);
		if (ctr[0]=='M') scanf("%d",&n),pos=n;
		else if (ctr[0]=='I')
		{
			scanf("%d",&n);
			for (int i=0;i<n;i++) ch[i]=readchar();
			ch[n]=0;
			text.insert(pos,ch);
		}
		else if (ctr[0]=='P') pos--;
		else if (ctr[0]=='N') pos++;
		else if (ctr[0]=='D') scanf("%d",&n),text.erase(pos,n);
		else if (ctr[0]=='G') scanf("%d",&n),text.copy(pos,n,ch),ch[n]=0,printf("%s\n",ch); 
	}
	return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter