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. Oracle sqlplus 语法

    目录: 0. FREFACE 1. 执行一个SQL脚本文件 2. 对当前的输入进行编辑 3. 重新运行上一次运行的sql语句 4. 将显示的内容输出到指定文件 5. 关闭spool输出 6.显示一个表 ...

  2. ASIHTTPRequest 详解 例子

    目录 目录 发起一个同步请求 创建一个异步请求 队列请求 请求队列上下文 ASINetworkQueues, 它的delegate提供更为丰富的功能 取消异步请求 安全的内存回收建议 向服务器端上传数 ...

  3. 如何将HashMap,按照value值排序

    这里要用到一个Comparator的接口,里面只有一个方法,compare(),我们实现这个接口就好,很简单 private class ValueComparator implements Comp ...

  4. java 中读取本地文件中字符

    java读取txt文件内容.可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了. 通过这条线路 ...

  5. .Net程序猿玩转Android开发---(3)登陆页面布局

    这一节我们来看看登陆页面如何布局.对于刚接触到Android开发的童鞋来说.Android的布局感觉比較棘手.须要结合各种属性进行设置,接下来我们由点入面来 了解安卓中页面如何布局,登陆页面非常eas ...

  6. mysql的replication(主从同步)总结

    很好的文章,对mysql的主从架构有深入理解. mysql主从同步,从master同步数据到slave慢的情况下,是不是可以改成多线程处理加快同步速度? 参考文章如下: MySQL Replicati ...

  7. IIS7.5 提示未在本地计算机上注册“Microsoft.Jet.OleDb.4.0”提供程序

    在WIN7 X64平台IIS7.5,使用Asp.net连接access数据库时候,提示:未在本地计算机上注册“Microsoft.Jet.OleDb.4.0”提供程序. 说明: 执行当前 Web 请求 ...

  8. 第一次启动MySQL时报错

    [root@localhost~]#/usr/local/webserver/mysql/bin/mysql_install_db --basedir=/usr/local/webserver/mys ...

  9. AFNetworking 3.0的GET和POST的使用

    POST: AFHTTPSessionManager *session = [AFHTTPSessionManager manager]; session.requestSerializer = [A ...

  10. PHP Sessions

    PHP Sessions PHP session 变量用于存储关于用户会话(session)的信息,或者更改用户会话(session)的设置.Session 变量存储单一用户的信息,并且对于应用程序中 ...