WZJ的数据结构(负十八)
难度级别:E; 运行时间限制:100000ms; 运行空间限制:700KB; 代码长度限制:2000000B
试题描述

对于前一段样例:

输入
输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目。 
第2行包含N个数字,描述初始时的数列。 
以下M行,每行一条命令,格式参见问题描述中的表格。为了考察垃圾回收的使用,我们精心准备了多组数据。。。
输出
对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。 
输入示例
9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 0
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
3 3
1 2 3
MAKE-SAME 1 3 3
MAX-SUM
MAX-SUM
输出示例
-1
10
1
10
9
9
其他说明
样例见题目图片。
你可以认为在任何时刻,数列中至少有1个数。 
输入数据一定是正确的,即指定位置的数在数列中一定存在。  
50%的数据中,任何时刻数列中最多含有100个数; 100%的数据中,任何时刻数列中最多含有500个数。  
100%的数据中,任何时刻数列中任何一个数字均在[-1 000, 1 000]内。 
100%的数据中,M ≤20 000,插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。
注意内存限制。请块状链表选手自重;由于数据不太好请Splay选手谨慎使用双旋。

更新:常数很小的一个版本,而且似乎要少coding一点。但是很容易写错?(雾

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
#define CH for(int d=0;d<=1;d++) if(ch[d])
using namespace std;
const int maxn=+,inf=-1u>>;inline int read();
int max(int a,int b,int c){return max(max(a,b),c);}
struct node{
node*fa,*ch[];
int x,sm,mx,lx,rx,siz,set;bool rev;
void init(){fa=ch[]=ch[]=NULL;x=sm=mx=lx=;siz=;set=inf;rev=false;return;}
void revt(){
swap(ch[],ch[]);swap(lx,rx);rev^=;return;
}
void sett(int tag){
set=x=tag;sm=tag*siz;mx=lx=rx=max(tag,tag*siz);return;
}
void down(){
if(rev){CH{ch[d]->revt();}rev=false;}
if(set!=inf){CH{ch[d]->sett(set);}set=inf;}
return;
}
void update(){
if(ch[]&&ch[]){
siz=+ch[]->siz+ch[]->siz;
sm=x+ch[]->sm+ch[]->sm;
lx=max(ch[]->lx,ch[]->sm+x+max(,ch[]->lx));
rx=max(ch[]->rx,ch[]->sm+x+max(,ch[]->rx));
mx=max(ch[]->mx,ch[]->mx,max(,ch[]->rx)+x+max(,ch[]->lx));
}
else if(ch[]){
siz=+ch[]->siz;
sm=x+ch[]->sm;
lx=max(ch[]->lx,ch[]->sm+x);
rx=x+max(,ch[]->rx);
mx=max(ch[]->mx,max(,ch[]->rx)+x);
}
else if(ch[]){
siz=+ch[]->siz;
sm=x+ch[]->sm;
lx=x+max(,ch[]->lx);
rx=max(ch[]->rx,ch[]->sm+x);
mx=max(ch[]->mx,x+max(,ch[]->lx));
}
else{
siz=;sm=x;lx=rx=mx=x;
} return;
}
}Splay[maxn],*root,*nodecnt;
queue<node*>RAM;
void nodeinit(){
nodecnt=Splay;return;
}
node*newnode(){
node*t;if(!RAM.empty()) t=RAM.front(),RAM.pop();
else t=nodecnt++;t->init();return t;
}
void del(node*&x){RAM.push(x);return;}
void deltree(node*&x){if(!x)return;deltree(x->ch[]);deltree(x->ch[]);del(x);return;}
int parent(node*x,node*&y){return (y=x->fa)?y->ch[]==x?:y->ch[]==x?:-:-;}
void rotate(node*x){
node*y,*z;int d1=parent(x,y),d2=parent(y,z);
if(y->ch[d1]=x->ch[d1^]) y->ch[d1]->fa=y;
y->fa=x;x->fa=z;x->ch[d1^]=y;
if(d2!=-) z->ch[d2]=x;
y->update();return;
}
void pushdown(node*x){
static node*s[maxn];int top=;
for(node*y;;x=y){
s[top++]=x;y=x->fa;
if(!y||(y->ch[]!=x&&y->ch[]!=x)) break;
} while(top--) s[top]->down();return;
}
node*splay(node*x){
pushdown(x);node*y,*z;int d1,d2;
while(true){
if((d1=parent(x,y))<) break;
if((d2=parent(y,z))<){rotate(x);break;}
if(d1==d2) rotate(y),rotate(x);
else rotate(x),rotate(x);
} x->update();return x;
}
node*find(node*x,int rank){
x->down();int kth=x->ch[]?x->ch[]->siz+:;
if(rank==kth) return x;
if(rank<kth) return find(x->ch[],rank);
else return find(x->ch[],rank-kth);
}
node*findlast(node*x){
while(x->ch[]) x->down(),x=x->ch[];return x;
}
void split(node*&x,node*&y,int a){
if(!a){y=x;x=NULL;return;}
x=splay(find(x,a));y=x->ch[];x->ch[]=NULL;
if(y)y->fa=NULL;x->update();return;
}
void split(node*&x,node*&y,node*&z,int a,int b){
split(x,z,b);split(x,y,a-);return;
}
void join(node*&x,node*y){
if(!x){x=y;return;}if(!y)return;
x=splay(findlast(x));x->ch[]=y;
if(y)y->fa=x;x->update();return;
}
void join(node*&x,node*y,node*z){
join(y,z);join(x,y);return;
}
int A[maxn];
void build(node*&x,int L,int R){
if(L>R)return;int M=L+R>>;x=newnode();x->x=A[M];
build(x->ch[],L,M-);build(x->ch[],M+,R);
if(x->ch[]) x->ch[]->fa=x;
if(x->ch[]) x->ch[]->fa=x;
x->update();return;
}
void insert(int pos,int num){
for(int i=;i<num;i++) A[i]=read();
node*x,*y;build(x,,num-);
split(root,y,pos);join(root,x,y);return;
}
void remove(int pos,int num){
node*x,*y;split(root,x,y,pos,pos+num-);join(root,y);deltree(x);return;
}
void settag(int pos,int num,int tag){
node*x,*y;split(root,x,y,pos,pos+num-);x->sett(tag);join(root,x,y);return;
}
void revtag(int pos,int num){
node*x,*y;split(root,x,y,pos,pos+num-);x->revt();join(root,x,y);return;
}
int maxsum(int pos,int num){
if(!num)return ;node*x,*y;split(root,x,y,pos,pos+num-);int ans=x->sm;join(root,x,y);return ans;
}
int maxssm(){return root->mx;}
void printer(node*x){
if(!x) return;x->down();
printer(x->ch[]);
printf("%d ",x->x);
printer(x->ch[]);
return;
}
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')sig=-;ch=getchar();}
while(isdigit(ch))x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<)putchar('-'),x=-x;
int len=,buf[];while(x)buf[len++]=x%,x/=;
for(int i=len-;i>=;i--)putchar(buf[i]+'');return;
}
void init(){
nodeinit();int n,m,pos,num;char s[];
while(scanf("%d%d",&n,&m)==){
for(int i=;i<n;i++) A[i]=read();build(root,,n-);
while(m--){
scanf("%s",s);
if(s[]=='M'&&s[]=='X'){write(maxssm());ENT;continue;}
pos=read();num=read();
if(s[]=='I') insert(pos,num);
else if(s[]=='D') remove(pos,num);
else if(s[]=='M') settag(pos,num,read());
else if(s[]=='R') revtag(pos,num);
else write(maxsum(pos,num)),ENT;
} deltree(root);
}
return;
}
void work(){
return;
}
void print(){
return;
}
int main(){init();work();print();return ;}

原来copy内存的不要命的做法。。。

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
#define CH for(int d=0;d<=1;d++) if(ch[d])
using namespace std;
const int maxn=+,inf=-1u>>;
int max(int a,int b,int c){return max(a,max(b,c));}
struct node{
node*fa,*ch[];
int x;bool rev;int siz,sm,set,lx,rx,mx;
node(){ch[]=ch[]=NULL;x=sm=;lx=rx=mx=-inf;set=inf;rev=false;siz=;}
void init(){ch[]=ch[]=NULL;x=sm=;lx=rx=mx=-inf;set=inf;rev=false;siz=;return;}
void revt(){swap(ch[],ch[]);swap(lx,rx);rev^=;return;}
void sett(int tag){x=set=tag;sm=tag*siz;lx=rx=mx=max(tag,tag*siz);return;}
void update();
void down(){
if(rev){CH{ch[d]->revt();}rev=false;}
if(set!=inf){CH{ch[d]->sett(set);}set=inf;}
return;
}
}Splay[maxn],*root;int nodecnt=;
queue<node*>RAM;
node*newnode(){
node*t;if(!RAM.empty()) t=RAM.front(),RAM.pop();
else t=&Splay[nodecnt++];t->init();return t;
}
void del(node*&x){RAM.push(x);return;}
void deltree(node*&x){
if(!x)return;deltree(x->ch[]);deltree(x->ch[]);del(x);return;
}
void copy(node*&x,node*y){
x->x=y->x;
x->lx=y->lx;
x->mx=y->mx;
x->rx=y->rx;
x->sm=y->sm;
x->siz=y->siz;
x->set=y->set;
x->rev=y->rev;
return;
}
void node::update(){
siz=;sm=x;lx=mx=rx=;node*n[];n[]=newnode();n[]=newnode();
CH{siz+=ch[d]->siz;sm+=ch[d]->sm;copy(n[d],ch[d]);}
lx=max(n[]->lx,n[]->sm+x+max(,n[]->lx));
rx=max(n[]->rx,n[]->sm+x+max(,n[]->rx));
mx=max(,n[]->rx)+x+max(,n[]->lx);
mx=max(n[]->mx,n[]->mx,mx);
del(n[]);del(n[]);
return;
}
int parent(node*x,node*&y){return (y=x->fa)?y->ch[]==x?:y->ch[]==x?:-:-;}
void rotate(node*x){
node*y,*z;int d1=parent(x,y),d2=parent(y,z);
if(y->ch[d1]=x->ch[d1^]) y->ch[d1]->fa=y;
y->fa=x;x->fa=z;x->ch[d1^]=y;
if(d2!=-) z->ch[d2]=x;
y->update();return;
}
void pushdown(node*x){
static node*s[maxn];int top=;
for(node*y;;x=y){
s[top++]=x;y=x->fa;
if(!y||(y->ch[]!=x&&y->ch[]!=x)) break;
} while(top--) s[top]->down();return;
}
node*splay(node*x){
pushdown(x);node*y,*z;int d1,d2;
while(true){
if((d1=parent(x,y))<) break;
if((d2=parent(y,z))<){rotate(x);break;}
if(d1==d2) rotate(y),rotate(x);
else rotate(x),rotate(x);
} x->update();return x;
}
node*find(node*x,int rank){
x->down();int kth=;if(x->ch[]) kth=x->ch[]->siz+;
if(rank==kth) return x;
if(rank<kth) return find(x->ch[],rank);
else return find(x->ch[],rank-kth);
}
void split(node*&x,node*&y,int a){
if(!a){y=x;x=NULL;return;}
x=splay(find(x,a));y=x->ch[];
x->ch[]=NULL;if(y)y->fa=NULL;x->update();return;
}
void split(node*&x,node*&y,node*&z,int a,int b){
split(x,z,b);split(x,y,a-);return;
}
void join(node*&x,node*y){
if(!x){x=y;return;}if(!y)return;
x=splay(find(x,x->siz));x->ch[]=y;
if(y)y->fa=x;x->update();return;
}
void join(node*&x,node*y,node*z){
join(y,z);join(x,y);return;
}
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')sig=-;ch=getchar();}
while(isdigit(ch))x=*x+ch-'',ch=getchar();
return x*sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<)putchar('-'),x=-x;
int len=,buf[];while(x)buf[len++]=x%,x/=;
for(int i=len-;i>=;i--)putchar(buf[i]+'');return;
}
int s[maxn];
void build(node*&x,int L,int R){
if(L>R)return;int M=L+R>>;
x=newnode();x->x=s[M];
build(x->ch[],L,M-);
build(x->ch[],M+,R);
if(x->ch[]) x->ch[]->fa=x;
if(x->ch[]) x->ch[]->fa=x;
x->update();return;
}
void insert(int pos,int num){
int ms=;for(int i=;i<num;i++) s[ms++]=read();
node*x,*y;build(x,,num-);
split(root,y,pos);join(root,x,y);return;
}
void remove(int L,int R){
node*x,*y;split(root,x,y,L,R);deltree(x);join(root,y);return;
}
void settag(int L,int R,int tag){
node*x,*y;split(root,x,y,L,R);x->sett(tag);join(root,x,y);return;
}
int getsum(int L,int R){
node*x,*y;split(root,x,y,L,R);int sm=x->sm;join(root,x,y);return sm;
}
int getssm(int L,int R){
node*x,*y;split(root,x,y,L,R);int mx=x->mx;join(root,x,y);return mx;
}
void reverse(int L,int R){
node*x,*y;split(root,x,y,L,R);x->revt();join(root,x,y);return;
}
void init(){
int n,Q;int pos,k,v;char str[];
while(scanf("%d%d",&n,&Q)==){
for(int i=;i<n;i++) s[i]=read();build(root,,n-);
while(Q--){
scanf("%s",str);
if(str[]=='I'){
pos=read();k=read();
insert(pos,k);
}
else if(str[]=='D'){
pos=read();k=read();
remove(pos,pos+k-);
}
else if(!strcmp(str,"MAKE-SAME")){
pos=read();k=read();v=read();
settag(pos,pos+k-,v);
}
else if(!strcmp(str,"REVERSE")){
pos=read();k=read();
reverse(pos,pos+k-);
}
else if(!strcmp(str,"GET-SUM")){
pos=read();k=read();
if(!k){puts("");continue;}
write(getsum(pos,pos+k-));ENT;
}
else write(getssm(,root->siz)),ENT;
} deltree(root);
}
return;
}
void work(){
return;
}
void print(){
return;
}
int main(){init();work();print();return ;}

COJ WZJ的数据结构(负十八)splay_tree的天堂的更多相关文章

  1. COJ 1010 WZJ的数据结构(十) 线段树区间操作

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1001 WZJ的数据结构(十) 难度级别:D: 运行时间限制:3000ms: ...

  2. COJ1012 WZJ的数据结构(十二)

    今天突然想写个树套树爽一爽(1810ms) 写的是树状数组套线段树(动态开节点) #include<cstdio> #include<cctype> #include<c ...

  3. COJ 0970 WZJ的数据结构(负三十)树分治

    WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...

  4. COJ 0990 WZJ的数据结构(负十)

    WZJ的数据结构(负十) 难度级别:D: 运行时间限制:5000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 给你一个N个节点的有根树,从1到N编号,根节点为1并给 ...

  5. COJ 0981 WZJ的数据结构(负十九)树综合

    WZJ的数据结构(负十九) 难度级别:E: 运行时间限制:3500ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 WZJ的数据结构中有很多都是关于树的.这让很多练习 ...

  6. [COJ0985]WZJ的数据结构(负十五)

    [COJ0985]WZJ的数据结构(负十五) 试题描述 CHX有一个问题想问问大家.给你一个长度为N的数列A,请你找到两个位置L,R,使得A[L].A[L+1].…….A[R]中没有重复的数,输出R- ...

  7. [COJ0988]WZJ的数据结构(负十二)

    [COJ0988]WZJ的数据结构(负十二) 试题描述 输入 见题目,注意本题不能用文件输入输出 输出 见题目,注意本题不能用文件输入输出 输入示例 输出示例 数据规模及约定 1≤N≤1500,M≤N ...

  8. COJ966 WZJ的数据结构(负三十四)

    WZJ的数据结构(负三十四) 难度级别:C: 运行时间限制:20000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给一棵n个节点的树,请对于形如"u  ...

  9. COJ970 WZJ的数据结构(负三十)

    WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...

随机推荐

  1. lesson9:分布式定时任务

    在实际的开发过程中,我们一定会遇到服务自有的定时任务,又因为现在的服务都是分布式的,但是对于定时任务,很多的业务场景下,还是只希望单台服务来执行,网上有很多分布式定时任务的框架,各位如感兴趣,可以自行 ...

  2. Java基础知识强化24:Java中异常

    1.什么是异常 ?       Java程序运行中,常常会遇到非正常的现象,这种情况称为运行错误.根据性质可以分为错误和异常.Java程序中(无论谁写的代码),所有抛出(throw)的异常都必须从Th ...

  3. 队列(链式存储)JAVA代码

      publicclassLinkQueue<T>{       //结点类     publicclassNode{         public T data;         pub ...

  4. ASP.NET-FineUI开发实践-8(二)

    把上回的做一些改进 1.点击grid2的行改变TriggerBox1的值 var v = $(item).find('.x-grid-cell-Name div.x-grid-cell-inner') ...

  5. maven第三章 maven使用入门

    3.1编写pom groupId 一个项目名称 artifactId 子项目(模块)名称 version 开发中的版本,稳定的版本 name 项目名称,方便信息交流 http://news.cnblo ...

  6. (转)SVN教程总结

    文章原地址:http://www.cnblogs.com/armyfai/p/3985660.html SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本, ...

  7. Android学习笔记:如何设置ImageView中图片的显示方式

    我们在用ImageView显示图片时,很多情况下图片的大小与ImageView的尺寸不是完全一样的.这时就涉及到该如何设置显示图片了. ImageView有个重要的属性是ScaleType,该属性用以 ...

  8. 1.tomcat部署项目的几种方式和weblogic部署方式及一点通讯

      第一种部署方式: 直接使用myeclipse 找到server服务 添加要部署的项目Add Deployment ,然后选中某个项目,首选Exploded Archive(development ...

  9. C/C++中的++a和a++

    代码: #include <iostream> #include <cstdio> using namespace std; int main(){ ; (++a)+=a; / ...

  10. Linux 从 sar 到 sar2html 的认识

    这些变形的工具.诸如:淘宝的Tsar.ksar.sar2html....等.都是通过抓取 sar的数据   所以在最终呈现的数据上变化不大.只是展现的手段和效果不一样而已      sar 是帮助我们 ...