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. Bundle捆绑压缩技术

    Bundle捆绑压缩技术由命名空间System.Web.Optimization中的类提供.顾名思义,这些类是用来优化Web页面性能的,它们通过压缩文件大小,捆绑文件(把多个文件合成一个下载文件)来实 ...

  2. 【转】Android应用底部导航栏(选项卡)实例

    现在很多android的应用都采用底部导航栏的功能,这样可以使得用户在使用过程中随意切换不同的页面,现在我采用TabHost组件来自定义一个底部的导航栏的功能. 我们先看下该demo实例的框架图: 其 ...

  3. excel操作小技巧

    excel拼接sql语句时,时间格式问题 问题:若直接插入时间的单元格 :="insert into t_entity_car (create_time,name,age) value (' ...

  4. python 多线程探索

    前面已经了解过了,python多线程效率较低的主要原因是存在GIL,即Global Interpreter Lock(全局解释器锁).这里继续详细的看下GIL的说明与如何避免GIL的影响,从而提高py ...

  5. react基础课程一简述JSX及目录关系

    简述JSX及目录关系 简述:它被称为JSX,它是JavaScript的语法扩展,JSX是一种模板语言,但它具有JavaScript的全部功能.所以学习jsx还是需要学习基础的javaScript的. ...

  6. Django_模板HTML

  7. struts2的acton标签中的ignoreContextParams属性和param子元素的冲突

    <s:action ignoreContextParams="true" executeResult="true" name="login&qu ...

  8. 【深入篇】Andorid中常用的控件及属性

    TextView  android:autoLink 设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接.可选值(none/web/email/phone/map/al ...

  9. 体验 Windows 系统 CVM

    添加角色功能: service.msc 设置自动服务,net start telnet

  10. 去除inline-block元素间距