您的位置:首页 > 其它

poj 3580 super-memo 非旋treap/splay 模板

2017-02-14 15:33 627 查看

题目大意

分析

模版题就不分析了

非旋treap/splay

注意

splay插入,revolve后重新连边后要连父亲

splay中不要pushup(你提取出来的那一段)

因为那没有pushdown的,pushup会有bug

solution1(splay)

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <algorithm>
typedef long long LL;
using namespace std;
const int M=200007;

inline int rd(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
}

inline LL lrd(){
LL x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
}

int n,m;
LL fir[M];
char s[13];

struct SPLAY{
int ch[2],p;
int rev,sz;
LL tag,val,mn;
void init(LL d){
val=mn=d;
tag=0;
rev=0;
sz=1;
ch[0]=ch[1]=p=0;
}
}a[M];
int tot,rt;

void totag(int x,LL d){
a[x].val+=d;
a[x].mn+=d;
a[x].tag+=d;
}

void torev(int x){
a[x].rev^=1;
}

void pushup(int x){
a[x].mn=a[x].val;
a[x].sz=1;
if(a[x].ch[0]){
a[x].mn=min(a[x].mn,a[a[x].ch[0]].mn);
a[x].sz+=a[a[x].ch[0]].sz;
}
if(a[x].ch[1]){
a[x].mn=min(a[x].mn,a[a[x].ch[1]].mn);
a[x].sz+=a[a[x].ch[1]].sz;
}
}

void pushdown(int x){
if(a[x].rev){
if(a[x].ch[0]) torev(a[x].ch[0]);
if(a[x].ch[1]) torev(a[x].ch[1]);
swap(a[x].ch[0],a[x].ch[1]);
a[x].rev^=1;
}
if(a[x].tag){
if(a[x].ch[0]) totag(a[x].ch[0],a[x].tag);
if(a[x].ch[1]) totag(a[x].ch[1],a[x].tag);
a[x].tag=0;
}
}

int build(int l,int r){
if(l>r) return 0;
int x=l+r>>1;
a[x].init(fir[x]);
a[x].ch[0]=build(l,x-1);
a[x].ch[1]=build(x+1,r);
if(a[x].ch[0]) a[a[x].ch[0]].p=x;
if(a[x].ch[1]) a[a[x].ch[1]].p=x;
pushup(x);
return x;
}

int find_kth(int x,int kth){
if(!x) return 0;
pushdown(x);
int cnt=a[a[x].ch[0]].sz+1;
if(kth==cnt) return x;
if(kth<cnt) return find_kth(a[x].ch[0],kth);
else return find_kth(a[x].ch[1],kth-cnt);
}

void rot(int x){
int y=a[x].p;
int z=a[y].p;
int D=a[y].ch[1]==x,ss=D^1;
if(z) a[z].ch[a[z].ch[1]==y]=x;
a[x].p=z;
a[y].p=x;
if(a[x].ch[ss]) a[a[x].ch[ss]].p=y;
a[y].ch[D]=a[x].ch[ss];
a[x].ch[ss]=y;
pushup(y);
pushup(x);
}

void splay(int x){
int y,z;
for(;a[x].p;rot(x)){
y=a[x].p;
z=a[y].p;
if(!z) continue;
if(z==rt) rot(x);
else if((a[z].ch[0]==y)==(a[y].ch[0]==x)) rot(y);
else rot(x);
}
}

int Spl(int kth){
kth++;
int x=find_kth(rt,kth);
splay(x);
rt=x;
return x;
}

void Add(int l,int r,LL d){
int x=Spl(l-1);
int y=Spl(r+1);
int z=a[x].ch[1];
totag(z,d);
pushup(x);
pushup(y);
}

void Ins(int l,LL d){
int x=Spl(l);
int y=Spl(l+1);
int z=a[x].ch[1]=++tot;
a[z].init(d);
a[z].p=x;//****
pushup(x);
pushup(y);
}

void Del(int l){
int x=Spl(l-1);
int y=Spl(l+1);
a[x].ch[1]=0;
pushup(x);
pushup(y);
}

void Getmin(int l,int r){
int x=Spl(l-1);
int y=Spl(r+1);
int z=a[x].ch[1];
printf("%lld\n",a[z].mn);
pushup(x);
pushup(y);
}

void Reverse(int l,int r){
int x=Spl(l-1);
int y=Spl(r+1);
int z=a[x].ch[1];
torev(z);
pushup(x);
pushup(y);
}

void Revolve(int l,int r,int mid){
int x=Spl(mid);
int y=Spl(r+1);
int z=a[x].ch[1];
a[x].ch[1]=0;
pushup(x);
pushup(y);
x=Spl(l-1);
y=Spl(l);
a[x].ch[1]=z;
a[z].p=x;//******
pushup(x);
pushup(y);
}

int main(){
int i,x,y,tms;
LL z;
n=rd();
for(i=1;i<=n;i++) fir[i]=lrd();
x=build(1,n);
tot=n+2;rt=n+1;
a[n+1].init(-1);
a[n+2].init(-1);
a[n+1].ch[1]=n+2;
a[n+2].p=n+1;
a[n+2].ch[0]=x;
a[x].p=n+2;
pushup(n+2);
pushup(n+1);

m=rd();
while(m--){
scanf("%s",s);
if(s[0]=='A'){
x=rd();y=rd();z=lrd();
Add(x,y,z);
}
else if(s[0]=='I'){
x=rd();z=lrd();
Ins(x,z);
}
else if(s[0]=='D'){
x=rd();
Del(x);
}
else if(s[0]=='M'){
x=rd(),y=rd();
Getmin(x,y);
}
else if(s[3]=='E'){
x=rd(),y=rd();
Reverse(x,y);
}
else{
x=rd(),y=rd();
tms=rd();
int len=y-x+1;
tms=(tms%len+len)%len;
tms=len-tms;
if(tms==len)continue;
Revolve(x,y,x+tms-1);
}
}
return 0;
}

solution2

#include <cstdio>
#include <cstring>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int M=200007;

inline int rd(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
}

inline LL lrd(){
LL x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return x;
}

int n,m;
char s[13];

struct DR{
int ch[2];
DR(){ch[0]=ch[1]=0;}
};

struct Treap{
LL val,mn,tag;
int rev,fix,sz;
int ch[2];
void init(LL d){
val=mn=d;
tag=0;
rev=0;
fix=rand();
ch[0]=ch[1]=0;
sz=1;
}
}a[M];
int root,tot;

void totag(int x,LL z){
a[x].val+=z;
a[x].mn+=z;
a[x].tag+=z;
}

void torev(int x){
a[x].rev^=1;
}

void pushup(int x){
a[x].mn=a[x].val;
a[x].sz=1;
if(a[x].ch[0]){
a[x].mn=min(a[x].mn,a[a[x].ch[0]].mn);
a[x].sz+=a[a[x].ch[0]].sz;
}
if(a[x].ch[1]){
a[x].mn=min(a[x].mn,a[a[x].ch[1]].mn);
a[x].sz+=a[a[x].ch[1]].sz;
}
}

void pushdown(int x){
if(a[x].rev){
if(a[x].ch[0]) torev(a[x].ch[0]);
if(a[x].ch[1]) torev(a[x].ch[1]);
swap(a[x].ch[0],a[x].ch[1]);
a[x].rev^=1;
}
if(a[x].tag){
if(a[x].ch[0]) totag(a[x].ch[0],a[x].tag);
if(a[x].ch[1]) totag(a[x].ch[1],a[x].tag);
a[x].tag=0;
}
}

DR split_kth(int x,int kth){
DR y;
if(!x) return y;
pushdown(x);
int cnt=1;
if(a[x].ch[0]) cnt+=a[a[x].ch[0]].sz;
if(cnt==kth){
y.ch[1]=a[x].ch[1];
a[x].ch[1]=0;
pushup(x);
y.ch[0]=x;
return y;
}
else if(kth<cnt){
y=split_kth(a[x].ch[0],kth);
a[x].ch[0]=y.ch[1];
pushup(x);
y.ch[1]=x;
return y;
}
else{
y=split_kth(a[x].ch[1],kth-cnt);
a[x].ch[1]=y.ch[0];
pushup(x);
y.ch[0]=x;
return y;
}
}

int merge(int x,int y){
if(!x) return y;
if(!y) return x;
if(a[x].fix<a[y].fix){
pushdown(x);
a[x].ch[1]=merge(a[x].ch[1],y);
pushup(x);
return x;
}
else{
pushdown(y);
a[y].ch[0]=merge(x,a[y].ch[0]);
pushup(y);
return y;
}
}

void Add(int x,int y,LL z){
DR n2=split_kth(root,y);
DR n1=split_kth(n2.ch[0],x-1);
totag(n1.ch[1],z);
root=merge(merge(n1.ch[0],n1.ch[1]),n2.ch[1]);
}

void Ins(int x,LL z){
a[++tot].init(z);
DR n1=split_kth(root,x);
root=merge(merge(n1.ch[0],tot),n1.ch[1]);

}

void Del(int x){
DR n2=split_kth(root,x);
DR n1=split_kth(n2.ch[0],x-1);
root=merge(n1.ch[0],n2.ch[1]);
}

void Getmin(int x,int y){
DR n2=split_kth(root,y);
DR n1=split_kth(n2.ch[0],x-1);
printf("%lld\n",a[n1.ch[1]].mn);
root=merge(merge(n1.ch[0],n1.ch[1]),n2.ch[1]);
}

void Reverse(int x,int y){
DR n2=split_kth(root,y);
DR n1=split_kth(n2.ch[0],x-1);
torev(n1.ch[1]);
root=merge(merge(n1.ch[0],n1.ch[1]),n2.ch[1]);
}

void Revolve(int x,int y,int z){
DR n2=split_kth(root,y);
DR n1=split_kth(n2.ch[0],x-1);
DR nw=split_kth(n1.ch[1],z);
root=merge(merge(n1.ch[0],merge(nw.ch[1],nw.ch[0])),n2.ch[1]);
}

int main(){
int i,x,y,tms;
LL z;
n=rd();
for(i=1;i<=n;i++){
z=lrd();
a[i].init(z);
}
root=0;
tot=n;
for(i=1;i<=n;i++) root=merge(root,i);
m=rd();
while(m--){
scanf("%s",s);
if(s[0]=='A'){
x=rd(),y=rd();
z=lrd();
Add(x,y,z);
}
else if(s[0]=='I'){
x=rd();
z=lrd();
Ins(x,z);
}
else if(s[0]=='D'){
x=rd();
Del(x);
}
else if(s[0]=='M'){
x=rd(),y=rd();
Getmin(x,y);
}
else if(s[3]=='E'){
x=rd(),y=rd();
Reverse(x,y);
}
else{
x=rd(),y=rd(),tms=rd();
int llen=y-x+1;
tms=(tms%llen+llen)%llen;
tms=llen-tms;
if(tms==llen) continue;
Revolve(x,y,tms);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: