您的位置:首页 > 其它

【splay】【bzoj 1895】: Pku3580 supermemo

2014-11-25 20:21 519 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1895

终于找到比较像样的模板题了

Orz 策爷单旋3s+ rank 3

我太弱双选无论怎么优化常数6s+

求神犇指导蒟蒻如何优化常数。。。。

难道写个struct会快。?

6540ms:

//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/************************************************
Code By willinglive    Blog:http://willinglive.cf
************************************************/
#define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
inline const int read()
{
int r=0,k=1;char c=getchar();
for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';
return k*r;
}
/////////////////////////////////////////////////
const int N=200005;
int n,m;
int a
,cnt;
int root,fa
,c
[2],sz
,id
;
int mi
,w
;
int add
;bool rev
;
int rec
;
/////////////////////////////////////////////////
inline int min(int a,int b){return a<b?a:b;}
#define LS c[o][0]
#define RS c[o][1]
inline void pushup(int o)
{
sz[o]=sz[LS]+sz[RS]+1;
mi[o]=w[o];
if(LS) mi[o]=min(mi[o],mi[LS]);
if(RS) mi[o]=min(mi[o],mi[RS]);
}
inline void modify(int o,int x)
{
if(!o)return;
w[o]+=x;mi[o]+=x;add[o]+=x;
}
inline void flip(int o)
{
if(!o)return;
rev[o]^=1;
swap(LS,RS);
}
inline void pushdown(int o)
{
int tmp;
if(tmp=add[o])
{
int l=LS,r=RS;
modify(LS,tmp); modify(RS,tmp);
add[o]=0;
}
if(rev[o])
{
flip(LS); flip(RS);
rev[o]=0;
}
}
void build(int l,int r,int o)
{
int now=id[l],last=id[o];
w[o]=mi[o]=a[o];
if(l==r)
{
sz[now]=1;
w[now]=mi[now]=a[l];
add[now]=rev[now]=0;
return;
}
RS=id[o+1+r>>1], fa[RS]=id[o];
if(l^o) LS=id[l+o-1>>1], fa[LS]=id[o];
if(l^o) build(l,o-1,l+o-1>>1); build(o+1,r,o+1+r>>1);
pushup(o);
}
inline void reclaim(int o)
{
if(!o) return;
fa[o]=LS=RS=sz[o]=mi[o]=w[o]=add[o]=rev[o]=0;
rec[++rec[0]]=o;
}
inline int newnode()
{
if(rec[0]) return rec[rec[0]--];
else return ++cnt;
}
int find(int o,int k)
{
while(1)
{
pushdown(o);
if(sz[LS]+1==k) return o;
if(k<=sz[LS]) o=LS;
else k-=sz[LS]+1,o=RS;
}
}
inline void rot(int x,int &k)
{
int y=fa[x],z=fa[y];
bool f=*c[y]!=x;
if(y==k)k=x;
else c[z][*c[z]!=y]=x;
int &t=c[x][!f];
fa[x]=z; fa[y]=x; fa[t]=y;
c[y][f]=t; t=y;
pushup(y);
}
void splay(int x,int &k=root)
{
while(x^k)
{
int y=fa[x],z=fa[y];
if(y^k)
{
if(*c[y]==x^*c[z]==y) rot(x,k);
else rot(y,k);
}rot(x,k);
}
}
void modify()
{
int l=read(),r=read(),x=read(); r+=2;
splay(l=find(root,l)); splay(r=find(root,r),c[root][1]);
int o=c[r][0];
add[o]+=x; w[o]+=x; mi[o]+=x;
}
void del()
{
int x=read(),y=x,o;
splay(x=find(root,x)); splay(y=find(root,y+2),c[root][1]);
o=c[y][0]; reclaim(o); c[y][0]=0;
pushup(y); pushup(x);
}
void insert()
{
int pos=read()+1,x=read(),y=pos+1;
splay(pos=find(root,pos)); splay(y=find(root,y),c[root][1]);
int &o=c[y][0]=newnode();
fa[o]=y;sz[o]=1;LS=RS=0;
w[o]=mi[o]=x; add[o]=rev[o]=0;
pushup(y); pushup(root);
}
void getmin()
{
int l=read(),r=read(); r+=2;
splay(l=find(root,l));
splay(r=find(root,r),c[root][1]);
printf("%d\n",mi[c[r][0]]);
}
void reverse()
{
int l=read(),r=read(); r+=2;
splay(l=find(root,l)); splay(r=find(root,r),c[root][1]);
flip(c[r][0]);
}
void revolve()
{
int l=read(),r=read(),k=read(); l++; r++;
k%=(r-l+1);
if(!k) return;
int x=r-k,y=r+1;
splay(x=find(root,x)); splay(y=find(root,y),c[root][1]);
int tmp=c[y][0];
c[y][0]=0;
pushup(y); pushup(x);
x=l-1; y=l;
splay(x=find(root,x)); splay(y=find(root,y),c[root][1]);
c[y][0]=tmp; fa[tmp]=y;
pushup(y); pushup(x);
}
/////////////////////////////////////////////////
void input()
{
n=read();
rep(i,1,n) a[i+1]=read();
n+=2; cnt=n;
a[1]=a
=0x3fffffff;
rep(i,1,n) id[i]=i;
}
void solve()
{
char op[10];
build(1,n,root=n+1>>1);
m=read();
while(m--)
{
scanf("%s",op);
if(op[0]=='A') modify();
else if(op[0]=='D') del();
else if(op[0]=='I') insert();
else if(op[0]=='M') getmin();
else if(op[3]=='E') reverse();
else revolve();
}
}
/////////////////////////////////////////////////
int main()
{
#ifndef _TEST
freopen("std.in","r",stdin); freopen("std.out","w",stdout);
#endif
input(),solve();
return 0;
}


改了一个小时的struct(今晚没事干么)貌似姿势还有点问题

删掉了回收功能,但代码复杂度增加了不少

3880ms

//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/************************************************
Code By willinglive    Blog:http://willinglive.cf
************************************************/
#define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
inline const int read()
{
int r=0,k=1;char c=getchar();
for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';
return k*r;
}
/////////////////////////////////////////////////
const int N=200005;
int n,m;
int a
,cnt;
int root,id
;
int rec
;
struct tree{
int o,fa,c[2],sz,mi,w,add;bool rev;
inline void pushup();
inline void modify(int x);
inline void flip();
inline void pushdown();
void build(int l,int r,int o);
}T
;
/////////////////////////////////////////////////
inline int min(int a,int b){return a<b?a:b;}
#define LS c[0]
#define RS c[1]
inline void tree::pushup()
{
sz=T[LS].sz+T[RS].sz+1;
mi=w;
if(LS) mi=min(mi,T[LS].mi);
if(RS) mi=min(mi,T[RS].mi);
}
inline void tree::modify(int x)
{
if(!this)return;
w+=x;mi+=x;add+=x;
}
inline void tree::flip()
{
if(!this)return;
rev^=1;
swap(LS,RS);
}
inline void tree::pushdown()
{
int tmp;
if(tmp=add)
{
int l=LS,r=RS;
T[LS].modify(tmp); T[RS].modify(tmp);
add=0;
}
if(rev)
{
T[LS].flip(); T[RS].flip();
rev=0;
}
}
void tree::build(int l,int r,int o)
{
int now=id[l],last=id[o];
w=mi=a[o];
if(l==r)
{
T[now].o=o;
T[now].sz=1;
T[now].w=T[now].mi=a[l];
T[now].add=T[now].rev=0;
return;
}
RS=id[o+1+r>>1], T[RS].fa=id[o];
if(l^o) LS=id[l+o-1>>1], T[LS].fa=id[o];
if(l^o) T[LS].build(l,o-1,l+o-1>>1); T[RS].build(o+1,r,o+1+r>>1);
T[o].pushup();
}
int find(int o,int k)
{
while(1)
{
T[o].pushdown();
if(T[T[o].LS].sz+1==k) return o;
if(k<=T[T[o].LS].sz) o=T[o].LS;
else k-=T[T[o].LS].sz+1,o=T[o].RS;
}
}
inline void rot(int x,int &k)
{
int y=T[x].fa,z=T[y].fa;
bool f=*T[y].c!=x;
if(y==k)k=x;
else T[z].c[*T[z].c!=y]=x;
int &t=T[x].c[!f];
T[x].fa=z; T[y].fa=x; T[t].fa=y;
T[y].c[f]=t; t=y;
T[y].pushup();
}
void splay(int x,int &k=root)
{
while(x^k)
{
int y=T[x].fa,z=T[y].fa;
if(y^k)
{
if(*T[y].c==x^*T[z].c==y) rot(x,k);
else rot(y,k);
}rot(x,k);
}
}
void modify()
{
int l=read(),r=read(),x=read(); r+=2;
splay(l=find(root,l));
splay(r=find(root,r),T[root].RS);
int o=T[r].LS;
T[o].modify(x);
}
void del()
{
int x=read(),y=x,o;
splay(x=find(root,x)); splay(y=find(root,y+2),T[root].RS);
o=T[y].LS; T[y].LS=0;
T[y].pushup(); T[x].pushup();
}
void insert()
{
int pos=read()+1,x=read(),y=pos+1;
splay(pos=find(root,pos)); splay(y=find(root,y),T[root].RS);
int &o=T[y].LS=++cnt;
T[o].o=o;
T[o].fa=y; T[o].sz=1; T[o].LS=T[o].RS=0;
T[o].w=T[o].mi=x; T[o].add=T[o].rev=0;
T[y].pushup(); T[root].pushup();
}
void getmin()
{
int l=read(),r=read(); r+=2;
splay(l=find(root,l));
splay(r=find(root,r),T[root].RS);
printf("%d\n",T[T[r].LS].mi);
}
void reverse()
{
int l=read(),r=read(); r+=2;
splay(l=find(root,l)); splay(r=find(root,r),T[root].RS);
T[T[r].LS].flip();
}
void revolve()
{
int l=read(),r=read(),k=read(); l++; r++;
k%=(r-l+1);
if(!k) return;
int x=r-k,y=r+1;
splay(x=find(root,x)); splay(y=find(root,y),T[root].RS);
int tmp=T[y].LS;
T[y].LS=0;
T[y].pushup(); T[x].pushup();
x=l-1; y=l;
splay(x=find(root,x)); splay(y=find(root,y),T[root].RS);
T[y].LS=tmp; T[tmp].fa=y;
T[y].pushup(); T[x].pushup();
}
/////////////////////////////////////////////////
void input()
{
n=read();
rep(i,1,n) a[i+1]=read();
n+=2; cnt=n;
a[1]=a
=0x3fffffff;
rep(i,1,n) id[i]=i;
}
void solve()
{
char op[10];
root=n+1>>1;
T[root].build(1,n,root=n+1>>1);
m=read();
while(m--)
{
scanf("%s",op);
if(op[0]=='A') modify();
else if(op[0]=='D') del();
else if(op[0]=='I') insert();
else if(op[0]=='M') getmin();
else if(op[3]=='E') reverse();
else revolve();
}
}
/////////////////////////////////////////////////
int main()
{
#ifndef _TEST
freopen("std.in","r",stdin); freopen("std.out","w",stdout);
#endif
input(),solve();
return 0;
}


Updated:Dec.5

成功借鉴了CLJ的模板超越了jcvb!!!

rank 3!!!!!

3456ms

这个好写多了,不过指针版太不熟悉,不容易调试

和Trie的模板趋于一致了

//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/************************************************
Code By willinglive    Blog:http://willinglive.cf
************************************************/
#define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
/////////////////////////////////////////////////
const int N=200005;
const int inf=0x3fffffff;
#define LS c[0]
#define RS c[1]
int n,a
,cnt;
struct node{
node *c[2],*fa; int sz;
int w,mi;
int add; bool rev;
bool d(){return this==fa->c[1];}
void setc(node *ch,int x){c[x]=ch;ch->fa=this;}
void Add(int x){w+=x; mi+=x; add+=x;}
void Flip(){rev^=1;swap(LS,RS);}
void pushup();
void pushdown();
void init();
void build(int o,int l,int r);
}*root,*null,T
;
int cntNode;
/////////////////////////////////////////////////
inline void pushrange(){root->RS->pushup();root->pushup();}
void node::pushup()
{
sz=1;
if(LS!=null) sz+=LS->sz;
if(RS!=null) sz+=RS->sz;
mi=w;
if(LS!=null&&mi>LS->mi) mi=LS->mi;
if(RS!=null&&mi>RS->mi) mi=RS->mi;
}
void node::pushdown()
{
if(add)
{
if(LS!=null) LS->Add(add);
if(RS!=null) RS->Add(add);
add=0;
}
if(rev)
{
if(LS!=null) LS->Flip();
if(RS!=null) RS->Flip();
rev=0;
}
}
node* NewNode()
{
T[cntNode].init();
return &T[cntNode++];
}
void node::build(int l,int r,int o)
{
w=mi=a[o];
if(l==r)
{
sz=1;
w=mi=a[o];
add=rev=0;
return;
}
RS=NewNode(), RS->fa=this;
if(l^o) LS=NewNode(), LS->fa=this;
if(l^o) LS->build(l,o-1,l+o-1>>1); RS->build(o+1,r,o+1+r>>1);
pushup();
}
void node::init()
{
c[0]=c[1]=fa=null;
sz=1;
w=mi=0;
add=rev=0;
}
void rot(node *o)
{
node *f=o->fa; bool d=o->d();
f->fa->setc(o,f->d());
f->setc(o->c[!d],d);
o->setc(f,!d);
f->pushup();
}
void splay(node *o,node *k=null)
{
while(o->fa!=k)
{
if(o->fa->fa==k) rot(o);
else o->d()==o->fa->d()?(rot(o->fa),rot(o)):(rot(o),rot(o));
}
o->pushup();
if(o->fa==null) root=o;
}
node* find(int k)
{
int sz;
for(node* o=root;;)
{
o->pushdown();
sz=o->LS->sz;
if(k==sz+1) return o;
o=o->c[k>sz];
if(k>sz) k-=sz+1;
}
}
node* getrange(int l,int r)
{
l--;r++;
splay(find(l)); splay(find(r),root);
return root->RS->LS;
}
void add()
{
int l=read(),r=read(),x=read(); l++;r++;
node *o=getrange(l,r);
o->Add(x);
}
void del()
{
int x=read(),y=x; x++; y++;
node *o=getrange(x,x);
root->RS->LS=o=null;
pushrange();
}
void insert()
{
int pos=read()+1,x=read(),y=pos+1;
node *o=getrange(pos+1,pos);
o=NewNode();
o->Add(x);
root->RS->setc(o,0);
pushrange();
}
void getmin()
{
int l=read(),r=read(); l++;r++;
node* o=getrange(l,r);
printf("%d\n",o->mi);
}
void reverse()
{
int l=read(),r=read(); l++;r++;
node *o=getrange(l,r);
o->Flip();
}
void revolve()
{
int l=read(),r=read(),k=read(); l++;r++;
k%=(r-l+1);
if(!k) return;
node *tmp=getrange(r-k+1,r);
root->RS->LS=null;
pushrange();
node *o=getrange(l,l-1);
root->RS->setc(tmp,0);
pushrange();
}
/////////////////////////////////////////////////
void input()
{
n=read();
rep(i,1,n) a[i+1]=read();
n+=2; cnt=n;
a[1]=a
=inf;
}
void solve()
{
char op[10];
null=NewNode(); null->sz=0;
root=NewNode();
root->build(1,n,n+1>>1);
for(int m=read();m--;)
{
scanf("%s",op);
if(op[0]=='A') add();
else if(op[0]=='D') del();
else if(op[0]=='I') insert();
else if(op[0]=='M') getmin();
else if(op[3]=='E') reverse();
else revolve();
}
}
/////////////////////////////////////////////////
int main()
{
#ifndef _TEST
freopen("std.in","r",stdin); freopen("std.out","w",stdout);
#endif
input(),solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: