您的位置:首页 > 其它

[bzoj3786] 星系探索

2016-03-24 21:15 417 查看
  splay&&树的dfs序。。。这姿势太神了。

  膜了半天题解。http://blog.csdn.net/PoPoQQQ/article/details/41649197

  其实写那么久主要还是因为。。我的splay模版是含有size域的那种。。。在这题就用不了了TAT(或者说加了也没什么用。。)

  改姿势感觉好蛋疼。。

  比较奇怪的是我改成递归建树后只快了不到1s= =。。时限40s我跑了39+s。。

  很好奇别人2K+代码是怎么写的= =

#include<cstdio>
#include<iostream>
#include<cstring>
#define ll long long
using namespace std;
const int maxn=100233;
struct zs{int too,pre;}e[maxn];
int tot,last[maxn];
int l[maxn],r[maxn],tim;
int ch[maxn<<1][2],numl[maxn<<1],numr[maxn<<1],fa[maxn<<1],v[maxn<<1],cnt;
ll sum[maxn<<1],add[maxn<<1];
int st[maxn<<1],top;
int gg[maxn<<1],val[maxn];
int i,j,k,n,m,x,y,rt;
int ra,fh;char rx,id;
inline int read(){
rx=getchar(),ra=0,fh=1;
while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
if(rx=='-')fh=-1,rx=getchar();
while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
}
inline void _add(int x,int q){
if(gg[x]==1)v[x]+=q;else if(gg[x]==2)v[x]-=q;
sum[x]+=(ll)(numl[x]-numr[x])*q,
add[x]+=q;
}
inline void upd(int x){
int l=ch[x][0],r=ch[x][1];
sum[x]=sum[l]+sum[r]+v[x],
numl[x]=numl[l]+numl[r]+(gg[x]==1),
numr[x]=numr[l]+numr[r]+(gg[x]==2);
}
inline void pushdown(int x){
if(!add[x])return;
if(ch[x][0])_add(ch[x][0],add[x]);
if(ch[x][1])_add(ch[x][1],add[x]);
add[x]=0;
}
inline void rotate(int x){
int f=fa[x],gfa=fa[f],l=ch[f][1]==x,r=l^1;
if(f!=rt)ch[gfa][ch[gfa][1]==f]=x;else rt=x;
fa[fa[fa[ch[f][l]=ch[x][r]]=ch[x][r]=f]=x]=gfa,upd(f);
}
inline void splay(int &rt,int x){
int f,gfa;
for(st[top=1]=f=x;fa[f];st[++top]=(f=fa[f]));
while(top)pushdown(st[top--]);
while(x!=rt){
f=fa[x],gfa=fa[f];
if(f!=rt)
rotate((ch[f][1]==x)!=(ch[gfa][1]==f)?x:f);
rotate(x);
}
upd(x);
}
inline int getmn(int x){while(ch[x][0])x=ch[x][0];return x;}
inline int getmx(int x){while(ch[x][1])x=ch[x][1];return x;}
inline int split(int x,int y){
int a,b;
splay(rt,x),a=getmx(ch[x][0]);
splay(rt,y),b=getmn(ch[y][1]);
splay(rt,a),splay(ch[a][1],b);
return ch[b][0];
}
inline void move(int a,int b){
int x,y,z=split(l[a],r[a]);
x=rt,y=ch[x][1],
ch[y][0]=0,upd(y),upd(x);
x=l[b],splay(rt,x),y=getmn(ch[x][1]),
splay(ch[x][1],y),ch[y][0]=z,fa[z]=y,upd(y),upd(x);
}
inline ll query(int a){x=split(l[1],l[a]);return sum[x];}
inline void change(int p,int q){int x=split(l[p],r[p]);_add(x,q);}
inline void insert(int a,int b){e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;}
inline void dfs(int x){
l[x]=++tim;gg[tim]=1,v[tim]=val[x];
for(int i=last[x];i;i=e[i].pre)dfs(e[i].too);
r[x]=++tim;gg[tim]=2,v[tim]=-val[x];
}
inline void build(int a,int b,int pre){
if(a>b)return;
int mid=(a+b)>>1;
if(pre)ch[pre][mid>pre]=mid;
fa[mid]=pre,
build(a,mid-1,mid),build(mid+1,b,mid);
upd(mid);
}
int main(){
tim=1;rt=1;gg[rt]=3;upd(rt);
n=read();
for(i=2;i<=n;i++)insert(read(),i);
for(i=1;i<=n;i++)val[i]=read();
dfs(1);
tim++;gg[tim]=3;
build(1,tim,0);rt=(1+tim)>>1;
for(m=read();m;m--){
for(id=getchar();id<'A'||id>'Z';id=getchar());
x=read();if(id!='Q')y=read();
if(id=='Q')printf("%lld\n",query(x));
if(id=='F')change(x,y);
if(id=='C')move(x,y);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: