3786: 星系探索

Time Limit: 40 Sec  Memory Limit: 256 MB
Submit: 1314  Solved: 425
[Submit][Status][Discuss]

Description

物理学家小C的研究正遇到某个瓶颈。

他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球。主星球没有依赖星球。

我们定义依赖关系如下:若星球a的依赖星球是b,则有星球a依赖星球b.此外,依赖关系具有传递性,即若星球a依赖星球b,星球b依赖星球c,则有星球a依赖星球c.

对于这个神秘的星系中,小C初步探究了它的性质,发现星球之间的依赖关系是无环的。并且从星球a出发只能直接到达它的依赖星球b.

每个星球i都有一个能量系数wi.小C想进行若干次实验,第i次实验,他将从飞船上向星球di发射一个初始能量为0的能量收集器,能量收集器会从星球di开始前往主星球,并收集沿途每个星球的部分能量,收集能量的多少等于这个星球的能量系数。

但是星系的构成并不是一成不变的,某些时刻,星系可能由于某些复杂的原因发生变化。

有些时刻,某个星球能量激发,将使得所有依赖于它的星球以及他自己的能量系数均增加一个定值。还有可能在某些时刻,某个星球的依赖星球会发生变化,但变化后依然满足依赖关系是无环的。

现在小C已经测定了时刻0时每个星球的能量系数,以及每个星球(除了主星球之外)的依赖星球。接下来的m个时刻,每个时刻都会发生一些事件。其中小C可能会进行若干次实验,对于他的每一次实验,请你告诉他这一次实验能量收集器的最终能量是多少。

Input

第一行一个整数n,表示星系的星球数。

接下来n-1行每行一个整数,分别表示星球2-n的依赖星球编号。

接下来一行n个整数,表示每个星球在时刻0时的初始能量系数wi.

接下来一行一个整数m,表示事件的总数。

事件分为以下三种类型。

(1)"Q di"表示小C要开始一次实验,收集器的初始位置在星球di.

(2)"C xi yi"表示星球xi的依赖星球变为了星球yi.

(3)"F pi qi"表示星球pi能量激发,常数为qi.

Output

对于每一个事件类型为Q的事件,输出一行一个整数,表示此次实验的收集器最终能量。

 

Sample Input

3
1
1
4 5 7
5
Q 2
F 1 3
Q 2
C 2 3
Q 2

Sample Output

9
15
25

HINT

n<=100000,m<=300000,1<di,xi<=n,wi,qi<=100000.保证操作合法。注意w_i>=0

Source

很好的一个题目,让我对splay的理解加深了很多
求路径的和,首先应该想到树转序列
但如果用链剖+线段树,是无法修改父子关系的
看了看题解,说的是splay+dfs序,感觉美妙
可以记录一颗子树的入点和出点,这样就把一颗子树转化成了一段区间,如果修改父子关系,整体把某颗子树区间移动到一个节点后面
如果要求树上点到根的权值和,可以选择差分,入点+ 出点-
维护子树需要维护子树中有多少入点和出点
一颗子树整体加上某个值时,标记区间,区间的根节点 +val*(入点数-出点数)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define F(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
#define maxn 200100
using namespace std;
int n,q,rt,top,cnt,tot;
int a[maxn],sta[maxn],head[maxn],fa[maxn],w[maxn],v[maxn],tag[maxn];
int c[maxn][],t[maxn][],s[maxn][];
ll sum[maxn];
struct edge_type
{
int next,to;
}e[maxn];
inline int read()
{
int x=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void add_edge(int x,int y)
{
e[++cnt]=(edge_type){head[x],y};head[x]=cnt;
}
inline void dfs(int x)
{
v[t[x][]=++tot]=a[x];w[tot]=;
for(int i=head[x];i;i=e[i].next) if (!t[e[i].to][]) dfs(e[i].to);
v[t[x][]=++tot]=-a[x];w[tot]=-;
}
inline void pushup(int x)
{
if (!x) return;
int l=c[x][],r=c[x][];
s[x][]=s[l][]+s[r][]+(w[x]==);
s[x][]=s[l][]+s[r][]+(w[x]==-);
sum[x]=sum[l]+sum[r]+(ll)v[x];
}
inline void update(int x,ll z)
{
if (!x) return;
sum[x]+=(ll)(s[x][]-s[x][])*z;
v[x]+=w[x]*z;
tag[x]+=z;
}
inline void pushdown(int x)
{
if (!x) return;
if (!tag[x]) return;
update(c[x][],tag[x]);
update(c[x][],tag[x]);
tag[x]=;
}
inline void rotate(int x,int &k)
{
int y=fa[x],z=fa[y],l=c[y][]==x,r=l^;
if (y!=k) c[z][c[z][]==y]=x;else k=x;
fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;
pushup(y);pushup(x);
}
inline void splay(int x,int &k)
{
for(int i=x;i;i=fa[i]) sta[++top]=i;
while (top) pushdown(sta[top--]);
while (x!=k)
{
int y=fa[x],z=fa[y];
if (y!=k)
{
if ((c[z][]==y)^(c[y][]==x)) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
inline int findmin(int x)
{
while (c[x][]) x=c[x][];
return x;
}
inline int findmax(int x)
{
while (c[x][]) x=c[x][];
return x;
}
inline void split(int x,int y)
{
splay(x,rt);
int t1=findmax(c[x][]);
splay(y,rt);
int t2=findmin(c[y][]);
splay(t1,rt);
splay(t2,c[t1][]);
}
inline void build(int l,int r,int f)
{
if (l>r) return;
int x=(l+r)>>;
fa[x]=f;c[f][x>f]=x;
if (l==r){sum[x]=v[x];s[x][]=w[x]==;s[x][]=-s[x][];return;}
build(l,x-,x);build(x+,r,x);
pushup(x);
}
int main()
{
n=read();
F(i,,n){int x=read();add_edge(x,i);}
F(i,,n) a[i]=read();
tot=;dfs();
build(,*n+,);
rt=n+;
q=read();
while (q--)
{
char ch=getchar();
while (ch<'A'||ch>'Z') ch=getchar();
if (ch=='Q')
{
int x=read();
splay(t[][],rt);splay(t[x][],c[rt][]);
printf("%lld\n",sum[c[c[rt][]][]]+(ll)v[rt]+(ll)v[c[rt][]]);
}
else if (ch=='F')
{
int x=read(),y=read(),z;
splay(t[x][],rt);splay(t[x][],c[rt][]);
z=c[rt][];
v[rt]+=w[rt]*y;v[z]+=w[z]*y;
update(c[z][],y);
pushup(z);pushup(rt);
}
else
{
int x=read(),y=read(),z,tmp;
split(t[x][],t[x][]);
z=c[rt][];tmp=c[z][];c[z][]=;
pushup(z);pushup(rt);
splay(t[y][],rt);
splay(findmin(c[rt][]),c[rt][]);
z=c[rt][];c[z][]=tmp;fa[tmp]=z;
pushup(z);pushup(rt);
}
}
return ;
}
 

bzoj3786星系探索 splay的更多相关文章

  1. BZOJ3786:星系探索(Splay,括号序)

    Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...

  2. bzoj3786星系探索(splay维护dfs序)

    Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...

  3. BZOJ3786: 星系探索 Splay+DFS序

    题目大意:给你一个树,支持三种操作,子树加,点到根的路径和,改变某一个点的父亲. 分析: 看起来像一个大LCT,但是很显然,LCT做子树加我不太会啊... 那么,考虑更换一个点的父亲这个操作很有意思, ...

  4. BZOJ3786 星系探索 【Splay维护dfs序】*

    BZOJ3786 星系探索 Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均 ...

  5. [BZOJ3786]星系探索

    [BZOJ3786]星系探索 试题描述 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个 ...

  6. [BZOJ3786] 星系探索(括号序列+Splay)

    3786: 星系探索 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 2191  Solved: 644[Submit][Status][Discuss ...

  7. 【BZOJ-3786】星系探索 Splay + DFS序

    3786: 星系探索 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 647  Solved: 212[Submit][Status][Discuss] ...

  8. [BZOJ3786]星系探索(伪ETT)

    3786: 星系探索 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1638  Solved: 506[Submit][Status][Discuss ...

  9. BZOJ3786星系探索——非旋转treap(平衡树动态维护dfs序)

    题目描述 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球没有依赖星球. ...

随机推荐

  1. 【iOS】OC-Quartz2D简单使用

    什么是Quartz2D Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统 作用 ? 1 2 3 4 5 6 7 8 9 <code>Quartz 2D能完成的工作 绘制图形 ...

  2. 2017 国庆湖南 Day5

    期望得分:76+80+30=186 实际得分:72+10+0=82 先看第一问: 本题不是求方案数,所以我们不关心 选的数是什么以及的选的顺序 只关心选了某个数后,对当前gcd的影响 预处理 cnt[ ...

  3. DELL EqualLogic PS存储硬盘故障数据恢复成功案例分享

    DELL EqualLogic PS4000采用虚拟ISCSI SAN阵列,为远程或分支办公室.部门和中小企业存储部署带来企业级功能.智能化.自动化和可靠性.以简化的管理.快速的部署及合理的价格满足了 ...

  4. 【笔记】HybridApp中使用Promise化的JS-Bridge

    背景: HybridApp,前端采用JS-bridge的方式调用Native的接口,如获取设备信息.拍照.人脸识别等 前端封装了调用库,每次调用Native接口,需要进行两步操作(1.在window下 ...

  5. 图数据库orientDB(1-2)例子

    http://gog.orientdb.com/index.html#/infotab 小朱25岁,出生在教师家庭并且有个姐姐小田,他现在奋斗在帝都.  那么SQL是这样滴!!! CREATE VER ...

  6. redis入门(01)redis的下载和安装

    参考链接: 命令手册 : http://www.redis.net.cn/order/ 菜鸟教程: http://www.runoob.com/redis/redis-install.html 一.概 ...

  7. 基于python的统计公报关键数据爬取 update

    由于之前存在的难以辨别市本级,全市相关数据的原因,经过考虑采用 把含有关键词的字段全部提取进行人工辨别的方法 在其余部分不改变的情况下,更改test部分 def test(real_Title,rea ...

  8. 分布式服务框架HSF

    最近在读阿里巴巴中台战略思想与架构这本书,so和大家分享一些我get到的东东. HSF是阿里巴巴内部的分布式服务框架,这个大家都很熟悉了,先上一张HSF的工作原理图: 这个图说明了HSF框架中每个组件 ...

  9. Java Class文件格式详解

    magic[4字节] 魔数,用来判断是否可以被虚拟机使用.固定值为0xCAFEBABE(咖啡宝贝)minor_version[2字节] 次版本号major_version[2字节] 主版本号,低版本的 ...

  10. python 报障系统(完)

    python 报障系统(完) 一.报障系统原理: 原理: 1. 简单管理 2. 角色多管理(权限) a. 登录 session放置用户信息(检测是否已经登录) session放置权限信息(检测是否有权 ...