【BZOJ1507】【NOI2003】Editor
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;
}
评论 (0)