1269: [AHOI2006]文本编辑器editor

Time Limit: 10 Sec Memory Limit: 162 MB

Submit: 2540 Solved: 923

[Submit][Status][Discuss]

Description

这些日子。可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器。你能帮助他吗?为了明白任务目标。可可对“文本编辑器”做了一个抽象的定义:





文本:由0个或多个字符构成的序列。这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格。

光标:在一段文本中用于指示位置的标记,能够位于文本的第一个字符之前,文本的最后一个字符之后或文本的某两个相邻字符之间。

文本编辑器:为一个能够对一段文本和该文本中的一个光标进行例如以下七条操作的程序。

假设这段文本为空,我们就说这个文本编辑器是空的。 编写一个程序: 建立一个空的文本编辑器。 从输入文件里读入一些操作指令并运行。

 对全部运行过的GET操作,将指定的内容写入输出文件。

Input

输入文件里第一行是指令条数N。下面是须要运行的N个操作。除了回车符之外,输入文件的全部字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。

Output

依次相应输入文件里每条GET指令的输出,不得有不论什么多余的字符。

Sample Input

10

Insert 13

Balanced eert

Move 2

Delete 5

Next

Insert 7

editor

Move 0

Get

Move 11

Rotate 4

Get

Sample Output

B

t

HINT

对输入数据我们有例如以下假定: MOVE操作不超过50 000个。INSERT、DELETE和ROTATE操作作的总个数不超过6 000。GET操作不超过20 000个,PREV和NEXT操作的总个数不超过20 000。

 全部INSERT插入的字符数之和不超过2M(1M=1 024*1 024)。 DELETE操作、ROTATE操作和GET操作运行时光标后必定有足够的字符。MOVE、PREV、NEXT操作不会把光标移动到非法位置。 输入文件没有错误。

模板题:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct Node{
Node *ch[2];
int r,s;
char v;
bool f;
Node(char v):v(v) {ch[0]=ch[1]=NULL; r=rand(); s=1; f=false;}
void update(){
s=1;
if(ch[0]!=NULL) s+=ch[0]->s;
if(ch[1]!=NULL) s+=ch[1]->s;
}
void pushdown(){
if(f){
if(ch[0]!=NULL) ch[0]->f=!ch[0]->f;
if(ch[1]!=NULL) ch[1]->f=!ch[1]->f;
swap(ch[0],ch[1]);
f=false;
}
}
}*root;
int n;
char ch[10];
Node *merge(Node* &x,Node* &y)
{
if(x==NULL) return y;
if(y==NULL) return x;
if(x->r < y->r){
if(x!=NULL) x->pushdown();
x->ch[1]=merge(x->ch[1],y);
if(x!=NULL) x->update();
return x;
}
else{
if(y!=NULL) y->pushdown();
y->ch[0]=merge(x,y->ch[0]);
if(y!=NULL) y->update();
return y;
}
}
void split(Node* &o,Node* &x,Node* &y,int now)
{
if(o==NULL){
x=y=NULL;
return ;
}
if(now==0){
x=NULL;
y=o;
return ;
}
if(now==o->s){
x=o;
y=NULL;
return ;
}
o->pushdown();
if((o->ch[0]==NULL? 0: o->ch[0]->s)>=now){
split(o->ch[0],x,y,now);
o->ch[0]=y;
o->update();
y=o;
}
else{
split(o->ch[1],x,y,now-(o->ch[0]==NULL? 0: o->ch[0]->s)-1);
o->ch[1]=x;
o->update();
x=o;
}
}
void insert(Node* &o,int now,int len)
{
int i;
Node *a,*b,*c;
char ss;
split(o,a,b,now);
for(i=1;i<=len;++i){
while(1){
scanf("%c",&ss);
if(ss>=32&&ss<=126) break;
}
c=new Node(ss);
a=merge(a,c);
}
o=merge(a,b);
}
void del(Node* &o,int now,int len)
{
Node *a,*b,*c,*d;
split(o,a,b,now);
split(b,c,d,len);
o=merge(a,d);
}
void rotate(Node* &o,int now,int len)
{
Node *a,*b,*c,*d;
split(o,a,b,now);
split(b,c,d,len);
if(c!=NULL) c->f=!c->f;
b=merge(c,d);
o=merge(a,b);
}
void print(Node* &o,int now)
{
Node *a,*b,*c,*d;
split(o,a,b,now);
split(b,c,d,1);
printf("%c\n",c->v);
b=merge(c,d);
o=merge(a,b);
}
int main()
{
int now=0,len;
scanf("%d",&n);
while(n--){
scanf("%*c%s",&ch);
if(ch[0]=='M') scanf("%d",&now);
if(ch[0]=='I'){
scanf("%d",&len);
insert(root,now,len);
}
if(ch[0]=='D'){
scanf("%d",&len);
del(root,now,len);
}
if(ch[0]=='R'){
scanf("%d",&len);
rotate(root,now,len);
}
if(ch[0]=='G') print(root,now);
if(ch[0]=='P') now-=1;
if(ch[0]=='N') now+=1;
}
}

1500: [NOI2005]维修数列

Time Limit: 10 Sec Memory Limit: 64 MB

Submit: 8948 Solved: 2691

[Submit][Status][Discuss]

Description

Input

输入文件的第1行包括两个数N和M,N表示初始时数列中数的个数。M表示要进行的操作数目。第2行包括N个数字,描写叙述初始时的数列。

下面M行。每行一条命令,格式參见问题描写叙述中的表格。

Output

对于输入数据中的GET-SUM和MAX-SUM操作。向输出文件依次打印结果,每一个答案(数字)占一行。

Sample Input

9 8

2 -6 3 5 1 -5 -3 6 3

GET-SUM 5 4

MAX-SUM

INSERT 8 3 -5 7 2

DELETE 12 1

MAKE-SAME 3 3 2

REVERSE 3 6

GET-SUM 5 4

MAX-SUM

Sample Output

-1

10

1

10

HINT

写起来比較麻烦,调试和好久。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
#define inf 210000000
struct Node{
Node *ch[2];
int v,r,s,sum,change,lmax,rmax,maxn;
bool f;
Node(int v):v(v) {ch[0]=ch[1]=NULL;r=rand();s=1;f=0;sum=lmax=rmax=maxn=v;change=inf;}
void update(){
s=1;
if(ch[0]!=NULL) s+=ch[0]->s;
if(ch[1]!=NULL) s+=ch[1]->s;
sum=v;
if(ch[0]!=NULL) sum+=ch[0]->sum;
if(ch[1]!=NULL) sum+=ch[1]->sum;
lmax=max((ch[0]==NULL?-inf:ch[0]->lmax),(ch[0]==NULL?0:ch[0]->sum)+v+max(0,(ch[1]==NULL?0:ch[1]->lmax)));
rmax=max((ch[1]==NULL?-inf:ch[1]->rmax),(ch[1]==NULL?0:ch[1]->sum)+v+max(0,(ch[0]==NULL?0:ch[0]->rmax)));
maxn=max(v,max((ch[0]==NULL?-inf:ch[0]->maxn),(ch[1]==NULL? -inf:ch[1]->maxn)));
maxn=max(maxn,max((ch[0]==NULL?-inf:ch[0]->rmax),(ch[1]==NULL?-inf:ch[1]->lmax))+v);
maxn=max(max(sum,maxn),max(lmax,rmax));
maxn=max(maxn,(ch[0]==NULL?0:ch[0]->rmax)+(ch[1]==NULL?0:ch[1]->lmax)+v);
}
void pushdown(){
if(f){
if(ch[0]!=NULL){
ch[0]->f=!ch[0]->f;
swap(ch[0]->lmax,ch[0]->rmax);
swap(ch[0]->ch[0],ch[0]->ch[1]);
}
if(ch[1]!=NULL){
ch[1]->f=!ch[1]->f;
swap(ch[1]->lmax,ch[1]->rmax);
swap(ch[1]->ch[0],ch[1]->ch[1]);
}
f=false;
}
if(change!=inf){
if(ch[0]!=NULL){
ch[0]->v=ch[0]->change=change;
ch[0]->sum=ch[0]->s*change;
ch[0]->maxn=ch[0]->lmax=ch[0]->rmax=(change<0?change:ch[0]->sum);
}
if(ch[1]!=NULL){
ch[1]->v=ch[1]->change=change;
ch[1]->sum=ch[1]->s*change;
ch[1]->maxn=ch[1]->lmax=ch[1]->rmax=(change<0?change:ch[1]->sum);
}
change=inf;
}
}
}*root;
int n,m;
char ch[20];
Node *merge(Node* &x,Node* &y)
{
if(x!=NULL) x->pushdown();
if(y!=NULL) y->pushdown();
if(x==NULL) return y;
if(y==NULL) return x;
if(x->r < y->r){
x->ch[1]=merge(x->ch[1],y);
if(x!=NULL) x->update();
return x;
}
else{
y->ch[0]=merge(x,y->ch[0]);
if(y!=NULL) y->update();
return y;
}
}
void split(Node* &o,Node* &x,Node* &y,int now)
{
if(o==NULL){
x=y=NULL;
return ;
}
o->pushdown();
if(now==0){
x=NULL;
y=o;
return ;
}
if(now==o->s){
x=o;
y=NULL;
return ;
}
if((o->ch[0]==NULL? 0: o->ch[0]->s)>=now){
split(o->ch[0],x,y,now);
o->ch[0]=y;
o->update();
y=o;
}
else{
split(o->ch[1],x,y,now-(o->ch[0]==NULL? 0: o->ch[0]->s)-1);
o->ch[1]=x;
o->update();
x=o;
}
}
void insert(Node* &o,int now,int len)
{
int i,x;
Node *a,*b,*c;
split(o,a,b,now);
for(i=1;i<=len;++i){
scanf("%d",&x);
c=new Node(x);
a=merge(a,c);
}
o=merge(a,b);
}
void del(Node* &o,int now,int len)
{
Node *a,*b,*c,*d;
split(o,a,b,now);
split(b,c,d,len);
o=merge(a,d);
}
void reverse(Node* &o,int now,int len)
{
Node *a,*b,*c,*d;
split(o,a,b,now);
split(b,c,d,len);
if(c!=NULL){
c->f=!c->f;
swap(c->lmax,c->rmax);
swap(c->ch[0],c->ch[1]);
}
b=merge(c,d);
o=merge(a,b);
}
void make_same(Node* &o,int now,int len,int change)
{
Node *a,*b,*c,*d;
split(o,a,b,now);
split(b,c,d,len);
if(c!=NULL){
c->v=c->change=change;
c->sum=c->s*change;
c->maxn=c->lmax=c->rmax=(change<0?change:c->sum);
}
b=merge(c,d);
o=merge(a,b);
}
void get(Node* &o,int now,int len)
{
Node *a,*b,*c,*d;
split(o,a,b,now);
split(b,c,d,len);
if(c!=NULL) printf("%d\n",c->sum);
else printf("0\n");
b=merge(c,d);
o=merge(a,b);
}
int main()
{
int i,len,now,change;
scanf("%d%d",&n,&m);
insert(root,0,n);
while(m--){
scanf("%*c%s",&ch);
if(ch[0]=='I'){
scanf("%d%d",&now,&len);
insert(root,now,len);
}
if(ch[0]=='D'){
scanf("%d%d",&now,&len);
del(root,now-1,len);
}
if(ch[2]=='K'){
scanf("%d%d%d",&now,&len,&change);
make_same(root,now-1,len,change);
}
if(ch[0]=='R'){
scanf("%d%d",&now,&len);
reverse(root,now-1,len);
}
if(ch[0]=='G'){
scanf("%d%d",&now,&len);
get(root,now-1,len);
}
if(ch[2]=='X') printf("%d\n",root->maxn);
}
}

[bzoj1269]文本编辑器editor [bzoj1500]维修数列的更多相关文章

  1. [BZOJ1269]文本编辑器editor

    Problem 有n个操作 Solution splay模板题,用splay维护下标. Notice 需要把l的前一个位置旋转到根,r的后一个位置旋转到根的右节点.所以特别要注意0的大坑. Code ...

  2. 【BZOJ1269/1507】[AHOI2006]文本编辑器editor Splay

    [BZOJ1269][AHOI2006]文本编辑器editor Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目 ...

  3. 【bzoj1507】[NOI2003]Editor /【bzoj1269】[AHOI2006]文本编辑器editor Splay

    [bzoj1507][NOI2003]Editor 题目描述 输入 输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作.其中: 为了使输入文件便于阅读,Insert操作的字符串中 ...

  4. BZOJ1269 [AHOI2006]文本编辑器editor 【82行splay】

    1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4633  Solved: 1782 [Sub ...

  5. 【BZOJ】【1269】【AHOI2006】文本编辑器editor

    Splay Splay序列维护的模板题了……为了便于处理边界情况,我们可以先插入两个空格当作最左端和最右端,然后……其实本题主要考察的就是Build.splay和Findkth这三个操作,我们可以实现 ...

  6. AHOI2006文本编辑器editor

    1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1885  Solved: 683[Submit ...

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

    splay..( BZOJ 1507 题目基本相同..双倍经验 ) ------------------------------------------------------------------ ...

  8. BZOJ_1269&&1507_[AHOI2006]文本编辑器editor&&[NOI2003]Editor

    BZOJ_1269&&1507_[AHOI2006]文本编辑器editor&&[NOI2003]Editor 题意: 分析: splay模拟即可 注意1507的读入格式 ...

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

    1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1213  Solved: 454[Submit ...

随机推荐

  1. Unix操作系统的入门与基础

    http://dev2dev.cnblogs.com/archive/2005/10/10/251894.aspx Unix操作系统的入门与基础 与大家熟悉的Windows用户界面和使用习惯不同,Un ...

  2. scp---远程拷贝文件

    scp命令用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器硬盘变为只读read onl ...

  3. 紫书 习题 10-17 UVa 11105 (筛法)

    类似于素数筛的思想去做,不然暴力会超时而且还要判重 #include<cstdio> #include<cstring> #include<vector> #def ...

  4. 剑指offer_面试题6_重建二叉树(分解步骤,逐个击破)

    题目:输入某二叉树的前序遍历和中序遍历的结果.请重建出该二叉树.如果输入的前序遍历和中序遍历的结果中都不含反复的数字. 比如:输入前序遍历 {1,2,4,7,3,5,6,8} 和中序遍历序列 {4,7 ...

  5. IOS基础学习日志(七)利用dispatch_once创建单例及使用

    自苹果引入了Grand Central Dispatch (GCD)(Mac OS 10.6和iOS4.0)后,创建单例又有了新的方法,那就是使用dispatch_once函数,当然,随着演进的进行. ...

  6. 慢慢人生路,学点Jakarta基础-集合类

    动态改变内存 因为数组在存储之前需要先申请一块连续的内存空间并且在编译的收就必须确定好它的空间大小,在运行时控件的大小无法再随着需求的改变而改变,极易出现越界的情况,数据少时又会造成内存空间浪费. 主 ...

  7. 39.Node.js域名解析---DNS模块

    转自:http://www.runoob.com/nodejs/nodejs-module-system.html Node.js DNS 模块用于解析域名.引入 DNS 模块语法格式如下: var ...

  8. flume中sink到hdfs,文件系统频繁产生文件和出现乱码,文件滚动配置不起作用?

    问题描述  解决办法 先把这个hdfs目录下的数据删除.并修改配置文件flume-conf.properties,重新采集. # Licensed to the Apache Software Fou ...

  9. 搭建并配置本地GitLab服务器教程

    由于工作单位不一定能够方便使用外部网络,现以下载rpm包来搭建一套本地GitLab服务器. 1. 系统准备 系统:redhat 7.3 2. 下载所需安装包 去官网下rpm包,下载地址,ce是免费的社 ...

  10. netstat -p 显示 -

    http://4735839.blog.51cto.com/4725839/1418945 https://yq.aliyun.com/articles/63060