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. springboot 统一管理异常信息

    新建ResponseEntityExceptionHandler的继承类:(依然,需要入口类扫描) /** * @author sky * @version 1.0 */ @ControllerAdv ...

  2. Hive的单节点集群详细启动步骤

    说在前面的话, 在这里,推荐大家,一定要先去看这篇博客,如下 再谈hive-1.0.0与hive-1.2.1到JDBC编程忽略细节问题 Hadoop Hive概念学习系列之hive三种方式区别和搭建. ...

  3. asp.net MVC4.0中几种控制器的区别

    空的MVC控制器MVC控制器的读/写操作和视图,使用实体框架MVC控制器带空的读/写操作空API控制器API控制器的读/写操作和视图,使用实体框架API控制器带空的读/写操作

  4. Mysql数据库常规操作(建表、查询)

    一.表单操作 1-1.创建表 create table tb_name( id in primary key auto_increment);    1-2.查看表 desc table_name; ...

  5. 单向链表 golang

    package main import "fmt" type Object interface {} //节点 type Node struct { data Object nex ...

  6. Top 22 Free Responsive HTML5 Admin & Dashboard Templates 2018

    Top 22 Free Responsive HTML5 Admin & Dashboard Templates 2018 May 18, 2018 Alex Ivanovs Website ...

  7. 编译安装 gcc 4.9并验证使用

    编译安装 gcc 4.9并验证使用 1. 准备环境(GCC 编译器) centOS 6.3 cat /proc/version Linux version 2.6.32-279.el6.x86_64 ...

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

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

  9. FragmentTransaction的commit和commitAllowingStateLoss的差别

    1.什么是FragmentTransaction? 使用Fragment时.能够通过用户交互来运行一些动作.比方添加.移除.替换等. 全部这些改变构成一个集合,这个集合被叫做一个transaction ...

  10. Cocos2d-x手机游戏开发与项目实践具体解释_随书代码

    Cocos2d-x手机游戏开发与项目实战具体解释_随书代码 作者:沈大海  因为原作者共享的资源为UTF-8字符编码.下载后解压在win下显示乱码或还出现文件不全问题,现完整整理,解决全部乱码问题,供 ...