【BZOJ3786】星系探索

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.保证操作合法。

题意:给出一棵树,要求有以下这些操作:

     1.求出一个节点到根的点权和。

     2.将一个节点的父亲改变。

     3.将一个子树中的每一个节点都加上一个权值

题解:主要是操作2,不然树链剖分可以强艹过,所以splay+dfs序即可。

 #include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<ctime> #define ll long long
#define N 200007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch>''||ch<''){if (ch=='-') f=-;ch=getchar();}
while(ch<=''&&ch>=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,q;
int rt,top,tot;
int a[N],sta[N],fa[N],w[N],v[N],tag[N];
int c[N][],t[N][],s[N][];
int cnt,head[N],next[N],rea[N];
ll sum[N]; void add(int u,int v)
{
next[++cnt]=head[u];
head[u]=cnt;
rea[cnt]=v;
}
void dfs(int u)
{
v[t[u][]=++tot]=a[u],w[tot]=;
for (int i=head[u];i!=-;i=next[i])
{
int v=rea[i];
if (!t[v][])
dfs(v);
}
v[t[u][]=++tot]=-a[u],w[tot]=-;
}
inline void pushup(int p)
{
if (!p) return;
int l=c[p][],r=c[p][];
s[p][]=s[l][]+s[r][]+(w[p]==);
s[p][]=s[l][]+s[r][]+(w[p]==-);
sum[p]=sum[l]+sum[r]+v[p];
}
inline void update(int p,ll z)
{
if (!p) return;
sum[p]+=(ll)(s[p][]-s[p][])*z;
v[p]+=w[p]*z;
tag[p]+=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]=;
}
void rotate(int x,int &k)
{
int y=fa[x],z=fa[y],l,r;
if (c[y][]==x) l=;else l=;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(x),pushup(y);
}
void splay(int x,int &k)
{
// cout<<" "<<x<<" "<<k<<endl;
for(int i=x;i;i=fa[i]) sta[++top]=i;
while (top) pushdown(sta[top--]);
while(x!=k)
{
//cout<<x<<" "<<k<<endl;
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;
}
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][]);
}
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()
{
memset(head,-,sizeof(head));
n=read();
for (int i=;i<=n;i++)
{
int x=read();
add(x,i);
}
for (int i=;i<=n;i++)
a[i]=read();
tot=,dfs();//增加哨兵。
build(,*n+,);
rt=(+*n+)>>; q=read();
while(q--)
{
char ch[];
scanf("%s",ch);
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);
}
}
}

bzoj 3786 星系探索 dfs+splay的更多相关文章

  1. BZOJ 3786: 星系探索 解题报告

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

  2. BZOJ 3786 星系探索 (splay+dfs序)

    题目大意:给你一棵树,支持一下三种操作 1.获取某节点到根节点的路径上所有节点的权值和 2.更换某棵子树的父亲 3.某子树内所有节点的权值都增加一个值w 当时想到了splay维护dfs序,查完题解发现 ...

  3. BZOJ 3786 星系探索 ——Splay

    子树可以移动,唔. 还是用Splay维护DFS序即可. 子树的话直接截取出来就好了. 然后求前驱后继可能麻烦一些. 添加两个虚拟节点会比较好写. #include <map> #inclu ...

  4. BZOJ 3786 星系探索

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

  5. BZOJ 3786: 星系探索 ETT

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

  6. BZOJ 3786: 星系探索 [伪ETT]

    传送门 数据,标程 题意: 一颗有根树,支持询问点到根路径权值和,子树加,换父亲 欧拉序列怎么求路径权值和? 一个点的权值只会给自己的子树中的点贡献,入栈权值正出栈权值负,求前缀和就行了! 和上题一样 ...

  7. BZOJ 3786: 星系探索 欧拉游览树

    一个叫 Euler-Tour-Tree 的数据结构,说白了就是用 Splay_Tree 维护欧拉序 #include <cstring> #include <algorithm> ...

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

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

  9. 【BZOJ3786】星系探索 DFS序+Splay

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

随机推荐

  1. elasticsearch6安装head插件

    1.head 插件Github地址:https://github.com/mobz/elasticsearch-head 2.npm install 3.npm run start 由于head插件监 ...

  2. AJPFX总结String类的特点

          String str = "abc"; str就是String的一个对象         字符串一旦被赋值, 值就不能再被改变了         举例:String s ...

  3. java课程设计全程实录——第0天

    本次课设计划在5月25日完成.目前还剩18天. 第0天主要完成事项如下: 搭建开发环境 制定开发进度规划表 阅读前人的课设 详细: 1.IDE的下载,安装,以及配合使用的阿里巴巴编程规约插件的安装与测 ...

  4. 后TOS时代的码头数字化生产力

    之前看过一篇文章是,是INFORM的副总裁写的关于以TOS外挂模式提升码头生产效能的文章.文章对外挂模式的总结挺好的,我最近也一直从事这块的工作,以此文梳理一下前面的经验,记录一下自己的感想. TOS ...

  5. ubuntu下安装memcache及memcached

    memcache 和 memcached 有什么区别呢? memcache最早是在2004年2月开发的,而memcached最早是在2009年1月开发的.所以memcache的历史比memcached ...

  6. python中 import 和from ... import 的区别

    先看一个例子: 我自定义的一个moudle,里面有一个方法sayhi,还有一个变量version#!/usr/bin/env python # coding=utf-8 # Filename: mym ...

  7. Vue 组件 data为什么是函数

    在创建或注册模板的时候,传入一个data属性作为用来绑定的数据.但是在组件中,data必须是一个函数,而不能直接把一个对象赋值给它. Vue.component('my-component', { t ...

  8. hdu 2192 MagicBuilding

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  9. 7-Java-C(四平方和)

    题目描述: 四平方和定理,又称为拉格朗日定理: 每个正整数都可以表示为至多4个正整数的平方和. 如果把0包括进去,就正好可以表示为4个数的平方和. 比如: 5 = 0^2 + 0^2 + 1^2 + ...

  10. 在虚拟机linux环境下编译windows版adb fastboot

    原文出自:http://blog.chinaunix.net/uid-20546441-id-1746200.html 我根据虚拟机编译遇到的问题进行一些添加 [前提条件] Linux Android ...