[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+代码是怎么写的= =
View Code
膜了半天题解。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
相关文章推荐
- POJ 1742 Coins
- POJ 3345 Bribing FIPA(树形dp+背包)
- 【BZOJ2659】算不出的算式,打表找规律
- 读《世界是数字的》有感
- android日常学习3-23 实现打字游戏
- HDU1272-小希的迷宫
- DBGridEh基本操作
- js+jq实现图片预览,支持到ie9+ff+chrome
- andorid 表格布局
- 【计算机视觉】积分图和积分直方图
- cocos2d-x 精灵 Sprite
- LeetCode#102. Binary Tree Level Order Traversal My Submissions Question
- PAT 乙级 1028.人口普查
- 简单客服系统
- HDU Today
- 单片机学习步骤工程师的经验分享
- Access中出现改变字段“自己主动编号”类型,不能再改回来!(已解决)
- TCP、UDP、HTTP、SOCKET介绍
- 2.3-string类型常用命令
- 侧拉菜单