bzoj 3786: 星系探索 splay
来源:互联网 发布:贵阳大数据是传销吗 编辑:程序博客网 时间:2024/06/05 04:26
bzoj真是坑爹,本地跑的差不多的程序,指针比数组快到不知道哪里去了。
然后我就开始了艰辛的卡常数,最终比很多指针快多辣~~~
由于有子树移动,那么考虑维护括号序列。也就是dfs入栈为'(',出栈为')',然后'('为正的权值。那么子树移动相当于平衡树的分裂和合并。用splay实现。
PS:求卡常数大神优化代码>.<
AC代码如下(目前最快的):
#include<bits/stdc++.h>#define ll long long#define N 200005using namespace std;int n,tot,tp,rt,a[N],fst[N],pnt[N],nxt[N],fa[N],c[N][2],q[N];struct node{ int sz,sc; ll icr,num,sum; }P[N];int read(){int x=0; char cr=getchar();while (cr<'0' || cr>'9') cr=getchar();while (cr>='0' && cr<='9'){ x=x*10+cr-'0'; cr=getchar(); }return x;}void add(int x,int y){pnt[++tot]=y; nxt[tot]=fst[x]; fst[x]=tot;}void maintain(int x){node &o=P[x],&l=P[c[x][0]],&r=P[c[x][1]];o.sz=l.sz+r.sz+1; o.sc=l.sc+r.sc+((x<=n)?1:-1);o.sum=l.sum+r.sum+o.num;}void mdy(int x,ll y){if (x){node &o=P[x];o.icr+=y; o.num+=(x<=n)?y:-y; o.sum+=o.sc*y;}}void pushdn(int x){ll &t=P[x].icr;if (t){mdy(c[x][0],t); mdy(c[x][1],t); t=0;}}void clr(int x){int i; q[tp=1]=x;for (i=x; i!=rt; i=fa[i]) q[++tp]=fa[i];while (tp) pushdn(q[tp--]);}int getby(int x,int l){int r=l^1;if (c[x][l]){for (x=c[x][l]; c[x][r]; x=c[x][r]); return x;} else{int y;for (y=fa[x]; y && c[y][l]==x; x=y,y=fa[y]); return y;}}void rot(int x,int &rt){int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1;if (y!=rt) c[z][c[z][1]==y]=x; else rt=x;fa[x]=z; fa[y]=x; fa[c[x][r]]=y;c[y][l]=c[x][r]; c[x][r]=y;maintain(y); } void splay(int x,int &rt){int i,y,z; clr(x);for (; x!=rt; rot(x,rt)){y=fa[x]; z=fa[y];if (y!=rt) rot((c[z][0]==y ^ c[y][0]==x)?x:y,rt);}maintain(x);}void dfs(int x,int last){int i,y; q[++tp]=x;for (i=fst[x]; i; i=nxt[i]){y=pnt[i];if (y!=last) dfs(y,x);}q[++tp]=x+n;}void build(int &rt,int l,int r,int last){if (l>r){ rt=0; return; }int mid=l+r>>1;rt=q[mid]; fa[rt]=last;build(c[rt][0],l,mid-1,rt); build(c[rt][1],mid+1,r,rt);P[rt].num=(rt<=n)?a[rt]:-a[rt-n];maintain(rt);}int main(){n=read();int i,x,y,l,r;for (i=2; i<=n; i++){x=read(); add(x,i); add(i,x);}for (i=1; i<=n; i++) a[i]=read();q[tp=1]=n<<1|1;dfs(1,0);q[++tp]=n+1<<1;build(rt,1,tp,0);int cas=read(); char cr; ll ans;while (cas--){cr=getchar(); while (cr<'A' || cr>'Z') cr=getchar();if (cr=='Q'){x=read(); clr(x);ans=P[c[x][0]].sum+P[x].num;for (y=fa[x]; x!=rt; x=y,y=fa[y])if (x==c[y][1]) ans+=P[c[y][0]].sum+P[y].num;printf("%lld\n",ans);} else if (cr=='C'){x=read(); y=read();l=getby(x,0); r=getby(x+n,1);splay(l,rt); splay(r,c[l][1]);x=c[r][0]; c[r][0]=0;maintain(r); maintain(l);splay(y,rt); r=getby(y,1); splay(r,c[y][1]);fa[x]=r; c[r][0]=x;maintain(r); maintain(y);} else if (cr=='F'){x=read(); y=getby(x+n,1); x=getby(x,0); splay(x,rt); splay(y,c[x][1]); mdy(c[y][0],read());}}return 0;}
by lych
2016.12.6
0 0
- bzoj 3786: 星系探索 splay
- BZOJ 3786 星系探索 DFS序+Splay
- bzoj 3786: 星系探索 dfs序+splay
- BZOJ 3786 星系探索 Splay维护树的入栈出栈序
- bzoj 3786: 星系探索(splay+dfs序)
- BZOJ 3786 星系探索 Splay维护DFS序
- BZOJ 3786 星系探索 splay维护dfs序
- 【BZOJ 3786】星系探索 splay维护dfs序
- BZOJ 3786: 星系探索
- BZOJ 3786 星系探索
- Bzoj3786星系探索:splay维护dfs序
- 【bzoj3786】【星系探索】【dfs序+splay】
- BZOJ3786: 星系探索 splay维护dfs序
- [BZOJ3786]星系探索(dfs序+splay)
- 【BZOJ】【P3786】【星系探索】【题解】【(伪)Top tree】
- BZOJ3786 星系探索
- [BZOJ3786]星系探索-ETT
- bzoj3786: 星系探索 //ETT
- 第一份工作,我在深圳
- 安卓音量+键的长按和短按分别处理不同的业务
- Oracle常用函数系列之四:数值函数(2)
- 最大子数问题
- 计算机导论 课本例子及习题集合 1.求平方根当数大于1
- bzoj 3786: 星系探索 splay
- ROS入门4: 理解ROS节点
- springMVC学习笔记(五) ---- 数据处理的几种方式
- 绘制轨迹设置途经点,并添加信息窗口
- dd
- 逻辑运算符一些值得注意的地方
- nginx+tomcat 动静分离
- zeromq 测试用例,一个简单的接受浏览器信息的例子
- h5学习之2(h5的常用标签和创建方法)