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. android实现界面左右滑动(GridView动态设置item,支持每个item按某个属性排序来显示在不同的界面)

    效果图 :                         分别是第一页.第二页.第三页,随手截的图,不整齐,勿见怪.开始走了弯路,废了不少时间. 思路如下: 1.用ViewPager实现左右分页滑动 ...

  2. VC++中操作XMLWin32实例

    摘要:VC++中操作XML XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini.VC++里操作XML有两个 ...

  3. 通知中心 NSNotificationCenter

    NSNotificationCenter 通知中心提供了一种在程序内广播信息的途径,一个NSNotificationCenter对象本质上是一个通知分发表(notification dispatch ...

  4. NYOJ 284 坦克大战 bfs + 优先队列

    这类带权的边的图,直接广搜不行,要加上优先队列,这样得到的结果才是最优的,这样每次先找权值最小的,代码如下 #include <stdio.h> #include <iostream ...

  5. C# SqlHelper

    操作数据库时,经常会把常用的方法封装到一个类中,这里简单写了一个SQLHelper类,供我平时调用. public static class SqlHelper { private static re ...

  6. java基础01

    1. /** * JDK: (Java Development ToolKit) java开发工具包.JDK是整个java的核心! * 包括了java运行环境 JRE(Java Runtime Env ...

  7. 简单竖向Tab选项卡

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  8. FileUpload 简单上传+小预览

    页面代码 : <form id="form1" runat="server"> <div> <asp:FileUpload ID= ...

  9. 嵌套repeater

    通过外层repeater的值来进行内层repeater的数据绑定 前台代码部分: <asp:repeater runat="server" id="repeater ...

  10. 初级班 Linux使用

    ifconfig 查看IP地址 重新启动网卡服务 service network restart 笔记 1.通过远程工具登陆到linux后,所在的位置是当前登录用户的家目录(home director ...