COJ WZJ的数据结构(负十八)splay_tree的天堂
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的天堂的更多相关文章
- COJ 1010 WZJ的数据结构(十) 线段树区间操作
传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1001 WZJ的数据结构(十) 难度级别:D: 运行时间限制:3000ms: ...
- COJ1012 WZJ的数据结构(十二)
今天突然想写个树套树爽一爽(1810ms) 写的是树状数组套线段树(动态开节点) #include<cstdio> #include<cctype> #include<c ...
- COJ 0970 WZJ的数据结构(负三十)树分治
WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...
- COJ 0990 WZJ的数据结构(负十)
WZJ的数据结构(负十) 难度级别:D: 运行时间限制:5000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 给你一个N个节点的有根树,从1到N编号,根节点为1并给 ...
- COJ 0981 WZJ的数据结构(负十九)树综合
WZJ的数据结构(负十九) 难度级别:E: 运行时间限制:3500ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 WZJ的数据结构中有很多都是关于树的.这让很多练习 ...
- [COJ0985]WZJ的数据结构(负十五)
[COJ0985]WZJ的数据结构(负十五) 试题描述 CHX有一个问题想问问大家.给你一个长度为N的数列A,请你找到两个位置L,R,使得A[L].A[L+1].…….A[R]中没有重复的数,输出R- ...
- [COJ0988]WZJ的数据结构(负十二)
[COJ0988]WZJ的数据结构(负十二) 试题描述 输入 见题目,注意本题不能用文件输入输出 输出 见题目,注意本题不能用文件输入输出 输入示例 输出示例 数据规模及约定 1≤N≤1500,M≤N ...
- COJ966 WZJ的数据结构(负三十四)
WZJ的数据结构(负三十四) 难度级别:C: 运行时间限制:20000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给一棵n个节点的树,请对于形如"u ...
- COJ970 WZJ的数据结构(负三十)
WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...
随机推荐
- open Session In View模式
首先看图说话: ****Open Session In View模式的主要思想是:在用户的每一次请求过程始终保持一个Session对象打开着*** 接下来就是代码: +++++++++++++++++ ...
- SpringMVC整合fastjson-1.1.41
以前用fastjson也只是硬编码,就好像这篇博文写的http://blog.csdn.net/jadyer/article/details/24395015 昨天心血来潮突然想和SpringMVC整 ...
- 转载:c++内存泄露机制
对于一个c/c++程序猿来说,内存泄漏是一个常见的也是令人头疼的问题.已经有很多技术被研究出来以应对这个问题,比方 Smart Pointer,Garbage Collection等.Smart Po ...
- Android入门之ActionBar实现Tab导航
效果图: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=&qu ...
- Android(java)学习笔记254:ContentProvider使用之内容观察者(观察发出去的短信)
1.新建一个案例如下: 2. 不需要添加权限,同时这里布局文件不做修改,来到MainActivity,如下: package com.itheima.sendsmslistener; import a ...
- ReSharper warning: Virtual member call in a constructor
1.构造函数的执行顺序是:基类--->派生类 2.如果虚方法被重写后,由于基类中调用了虚方法,此时调用的是最外层的被重写后的虚方法,此时可能会发生异常 举例: class Parent { pu ...
- bootstrap初探2
控制是否显示:visible-(lg | md | sm |sx)-(block | inline | inline-block), hidden-(lg | md | sm |sx) <!DO ...
- vs连接mysql
1.打开vs2012在aspx中添加一个Grid view 控件,,. 2,选择新建数据源. 3,选择数据库. 4,选择新建连接. 5,更改成mysql连接. 6,这里的Server name 是你自 ...
- Windows7电脑上不去网,ipconfig查询时默认网关会出现0.0.0.0问题的解决
用ipconfig查看网络配置,发现其他都正确,唯独默认网关上多了一条0.0.0.0的记录,.禁用网络连接再启用也不能恢复.网上找了一下有说改注册表的,打开注册表找到 HKEY_LOCAL_MACHI ...
- clang: error: unable to execute command: Segmentation fault: 11
我在Archive的时候出现了上面这个错误, 解决方法很简单: After huge trying I have disabled the Bitcode in Project's Target-&g ...