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);
}
}