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. 19.浏览器Window服务($window)

    转自:https://www.cnblogs.com/best/tag/Angular/ 引用浏览器的window对象.默认浏览器的window是全局的根对象. 示例代码: <!DOCTYPE ...

  2. 之前搭建的jenkins的一些笔记

    wget -O /etc/yum.repos.d/jenkins.repo http://jenkins-ci.org/redhat/jenkins.repo rpm --import http:// ...

  3. 24.桌面移动qq

    #include <stdlib.h> #include <Windows.h> #include <stdio.h> #include <math.h> ...

  4. 将本地的代码上传到网上SVN库

    使用VisualSVN Server创建版本库: https://jingyan.baidu.com/article/db55b609f6aa724ba20a2f6c.html 最详细的教程: htt ...

  5. CentOS下部署巡风步骤详解

    本博客已经迁移到新的网站,www.je2se.com,请大家移步关注,互相交流,共同成长 巡风Centos 6.5部署指南 基础环境要求: Python2.7+ 安装Centos相关依赖 # Cent ...

  6. Selenium_WebDriver操作iFrame日历框和复选框_Java

    iFrame日历框 页面上遇到iFrame元素时,先用findElement找到这个iFrame元素,然后再WebDriver.switchTo().frame(calFrame).在iFrame里操 ...

  7. HDU1788 Chinese remainder theorem again【中国剩余定理】

    题目链接: pid=1788">http://acm.hdu.edu.cn/showproblem.php?pid=1788 题目大意: 题眼下边的描写叙述是多余的... 一个正整N除 ...

  8. Python: PS 图像调整--对比度调整

    本文用 Python 实现 PS 里的图像调整–对比度调整.具体的算法原理如下: (1).nRGB = RGB + (RGB - Threshold) * Contrast / 255 公式中,nRG ...

  9. Fedora Core 11 Alpha试用视频(由于youtube问题暂时无法访问)

    1.系统安装: http://www.youtube.com/watch?v=QcDy5eRQZ20   2.重启后配置   3.体验Fedora 11 Gnome2.25和Kde 4.2 http: ...

  10. c# array arraylist 泛型list

    1 array 数组  是存储相同类型元素的固定大小的数据的顺序集合.在内存中是连续存储的,所以索引速度非常快,而且赋值和修改元素也非常简单. //定义字符串数组 大小为3 string[] str1 ...