BZOJ 1269 【AHOI2006】 文本编辑器editor

题目链接:文本编辑器editor

  这道题没啥好说的,直接上\(Splay\)就行了,板子题……

  但是我某个地方忘了下放标记导致调了一晚上

  保存一发板子:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 1024*1024*2+10

using namespace std;
typedef long long llg;

int m,rt,tt,now,n;
int s[maxn][2],fa[maxn],siz[maxn];
char ss[maxn],val[maxn];
bool rev[maxn];

int getint(){
	int w=0;bool q=0;
	char c=getchar();
	while((c>‘9‘||c<‘0‘)&&c!=‘-‘) c=getchar();
	if(c==‘-‘) c=getchar(),q=1;
	while(c>=‘0‘&&c<=‘9‘) w=w*10+c-‘0‘,c=getchar();
	return q?-w:w;
}

void update(int x){siz[x]=siz[s[x][0]]+siz[s[x][1]]+1;}
void rotate(int x,int &k){
	int p=fa[x],g=fa[p];
	bool l=(x==s[p][1]),r=!l;
	if(p==k) k=x;
	else s[g][p==s[g][1]]=x;
	fa[s[x][r]]=p; s[p][l]=s[x][r];
	s[x][r]=p; fa[p]=x; fa[x]=g;
	update(p),update(x);
}

void splay(int x,int &k){
	while(x!=k){
		int p=fa[x],g=fa[p];
		if(p!=k){
			if((x==s[p][1])^(p==s[g][1])) rotate(x,k);
			else rotate(p,k);
		}
		rotate(x,k);
	}
}

int find(int x){
	int u=rt,l,r; x++;
	while(u){
		l=s[u][0],r=s[u][1];
		if(rev[u]){
			rev[l]^=1,rev[r]^=1; rev[u]=0;
			swap(l,r),swap(s[u][0],s[u][1]);
		}
		if(siz[l]+1==x) break;
		if(siz[l]>=x) u=l;
		else x-=siz[l]+1,u=r;
	}
	return u;
}

int split(int l,int r){
	splay(find(l-1),rt); splay(find(r+1),s[rt][1]);
	return s[s[rt][1]][0];
}

int build(int l,int r){
	if(l>r) return 0;
	int u=++tt,mid=(l+r)>>1;
	s[u][0]=build(l,mid-1),s[u][1]=build(mid+1,r);
	fa[s[u][0]]=u,fa[s[u][1]]=u,val[u]=ss[mid];
	update(u); return u;
}

int main(){
	File("a");
	m=getint(); rt=1; tt=5;
	s[1][0]=2; s[1][1]=3; s[3][0]=4; s[3][1]=5;
	fa[4]=fa[5]=3; fa[2]=fa[3]=1;
	for(int i=5;i;i--) update(i),val[i]=‘ ‘;
	while(m--){
		scanf("%s",ss); int u,v;
		if(ss[0]==‘M‘) now=getint();
		else if(ss[0]==‘P‘) now--;
		else if(ss[0]==‘N‘) now++;
		else if(ss[0]==‘G‘) printf("%c\n",val[find(now+1)]);
		else if(ss[0]==‘I‘){
			n=getint();
			for(int i=1;i<=n;i++) ss[i]=getchar();
			v=build(1,n); split(now+1,now); u=s[rt][1];
			s[u][0]=v; fa[v]=u; while(u) update(u),u=fa[u];
		}
		else{
			n=getint(); u=split(now+1,now+n);
			if(ss[0]==‘R‘) rev[u]^=1;
			else{
				s[fa[u]][0]=0; fa[u]=0;
				update(s[rt][1]); update(rt);
			}
		}
	}
	return 0;
}
时间: 2024-12-20 22:21:03

BZOJ 1269 【AHOI2006】 文本编辑器editor的相关文章

BZOJ 1269: [AHOI2006]文本编辑器editor( splay )

splay..( BZOJ 1507 题目基本相同..双倍经验 ) ----------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ; i <

bzoj 1269 [AHOI2006]文本编辑器editor

原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1269 伸展树的运用,如下: 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using std::swap; 7 const int Max_N = 3000010; 8 stru

1269: [AHOI2006]文本编辑器editor

1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4718  Solved: 1807[Submit][Status][Discuss] Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或多个字符构成的序列.这些字符的ASCII码在闭区间[32,

AHOI2006文本编辑器editor

1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1885  Solved: 683[Submit][Status] Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或多个字符构成的序列.这些字符的ASCII码在闭区间[32, 126]内,也就是说

【BZOJ1269】[AHOI2006]文本编辑器editor Splay

[BZOJ1269][AHOI2006]文本编辑器editor Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对"文本编辑器"做了一个抽象的定义:   文本:由0个或多个字符构成的序列.这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格.光标:在一段文本中用于指示位置的标记,可以位于文本的第一个字符之前,文本的最后一个字符之后或文本的某两个相邻字符之间

[AHOI2006]文本编辑器editor

一不小心又开启了每天昏迷24个小时的状态,脑子不清醒的时候就该去看动画片. 只需要记录光标的位置即可,剩下的就是Splay的经典操作了,不多说了,我只是为了测试模板. #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath>

[AHOI2006]文本编辑器editor (Splay tree)

我感觉伸展树越来越模版了,没想到这么轻易的就过了... 把光标位置标记为pos MOVE:pos++或者pos-- INSERT:把光标旋转至根部,然后把光标后一个字母旋转至根的右子树,然后把insert的内容插入到root的右子树的左子树 ROTATE:把光标旋转至根部,然后把光标后一个字母旋转至根的右子树,然后把rev[root10]取反 GET:得到光标位置的后继,可以GET_KTH后然后GET_NEXT,也可以直接旋转,或者旋转后GET_MIN PREV,NEXT:都只需要改变光标位置变

[bzoj1269][AHOI2006文本编辑器editor] (splay模版题)

Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或多个字符构成的序列.这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格.光标:在一段文本中用于指示位置的标记,可以位于文本的第一个字符之前,文本的最后一个字符之后或文本的某两个相邻字符之间.文本编辑器:为一个可以对一段文本和该文本中的一个光标进行如下七条操作的程

【BZOJ 1269】 [AHOI2006]文本编辑器editor

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] /* [move k] 指令.直接 把pos改成k.表示改变光标位置 [insert n s],在pos后面插入一个长度为n的字符串. 这个操作. 我们可以先找出第pos个节点x和第pos+1个节点y (这里其实就是找第pos小的数,在splay上,加一个size大小域,找第k小即可.) (伸展树在旋转的过程中,不会影响性质,即,它中序遍历的结果始终是字符串s1..n) 我们执行splay x 0 再执行splay y x 然后

【rope】bzoj1269 [AHOI2006]文本编辑器editor

维护一个字符串,支持以下操作: 主要就是 成段插入.成段删除.成段翻转.前两个操作很好通过rope实现.第三个操作也不难,维护两个rope,一个正向,一个反向,翻转时swap一下就行了. rope教程: http://blog.csdn.net/iamzky/article/details/38348653 Code(Orz zky): 1 #include<cstdio> 2 #include<ext/rope> 3 using namespace std; 4 using na