3786: 星系探索

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的事件,输出一行一个整数,表示此次实验的收集器最终能量。


第一次见到这么用DFS序的...学习了一下姿势。

思路:对每个点进去和出来分别维护一个dfs序,然后进去的贡献为正,出来的贡献为负,这样你查询链的时候就可以直接查询出来贡献的左边一个的前缀值,不在链上的肯定差分掉了。

于是我们发现这个题就是要区间修改,区间移动,前缀查询就可以了。

区间移动的写splay可能比较方便。


Code:

#include <cstdio>
#define ls ch[now][0]
#define rs ch[now][1]
#define fa par[now]
#define ll long long
const int N=2e5+10;
int ch[N][2],par[N],dat[N],exist[N],siz[N],s[N],tot,root;
ll sum[N],tag[N];
void updata(int now){sum[now]=sum[ls]+sum[rs]+dat[now],siz[now]=siz[ls]+siz[rs]+exist[now];}
int identity(int now){return ch[fa][1]==now;}
void connect(int f,int now,int typ){ch[fa=f][typ]=now;}
void pushdown(int now)
{
if(tag[now])
{
sum[ls]+=tag[now]*siz[ls];
sum[rs]+=tag[now]*siz[rs];
if(ls) dat[ls]+=tag[now]*exist[ls];
if(rs) dat[rs]+=tag[now]*exist[rs];
tag[ls]+=tag[now],tag[rs]+=tag[now];
tag[now]=0;
}
}
void Rotate(int now)
{
int p=fa,typ=identity(now);
connect(p,ch[now][typ^1],typ);
connect(par[p],now,identity(p));
connect(now,p,typ^1);
updata(p),updata(now);
}
void splay(int now,int to)
{
to=par[to];
while(now) s[++tot]=now,now=fa;
while(tot) pushdown(s[tot--]);
now=s[1];
for(;fa!=to;Rotate(now))
if(par[fa]!=to)
Rotate(identity(now)^identity(fa)?now:fa);
if(!to) root=now;
}
void query(int now)
{
splay(now,root);
printf("%lld\n",sum[ls]+dat[now]);
}
int pre(int now)
{
splay(now,root);
now=ls;
while(rs) now=rs;
return now;
}
int suc(int now)
{
splay(now,root);
now=rs;
while(ls) now=ls;
return now;
}
void modify(int l,int r,ll d)
{
l=pre(l),r=suc(r);
splay(r,root),splay(l,ch[r][0]);
int now=ch[l][1];
tag[now]+=d,sum[now]+=d*siz[now],dat[now]+=d*exist[now];
updata(l),updata(r);
}
void change(int l,int r,int to)//把区间[l,r]接到to的右子树
{
l=pre(l),r=suc(r);
splay(r,root),splay(l,ch[r][0]);
int now=ch[l][1];
par[now]=ch[l][1]=0;
updata(l),updata(r);
int ri=suc(to);
splay(ri,ch[to][1]);
connect(ri,now,0);
updata(ri),updata(to);
}
int head[N],to[N<<1],Next[N<<1],cnt;
void add(int u,int v)
{
to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
}
int dfn[N],low[N],a[N],f[N],n,m,dfsclock=1;
void dfs(int now)
{
dat[dfn[now]=++dfsclock]=a[now];
exist[dfsclock]=1;
for(int v,i=head[now];i;i=Next[i])
if((v=to[i])!=f[now])
dfs(v);
dat[low[now]=++dfsclock]=-a[now];
exist[dfsclock]=-1;
}
void build(int &now,int l,int r)
{
if(l>r){now=0;return;}
now=l+r>>1;
build(ls,l,now-1),build(rs,now+1,r);
par[ls]=par[rs]=now;
updata(now);
}
int main()
{
scanf("%d",&n);
for(int i=2;i<=n;i++)
scanf("%d",f+i),add(i,f[i]),add(f[i],i);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
dfs(1);
build(root,1,++dfsclock);par[0]=0;
char op[5];
scanf("%d",&m);
for(int d,x,y,i=1;i<=m;i++)
{
scanf("%s",op);
if(op[0]=='Q')
{
scanf("%d",&d);
query(pre(low[d]));
}
else if(op[0]=='C')
{
scanf("%d%d",&x,&y);
change(dfn[x],low[x],dfn[y]);
}
else
{
scanf("%d%d",&x,&y);
modify(dfn[x],low[x],y);
}
}
return 0;
}

2018.12.11

BZOJ 3786: 星系探索 解题报告的更多相关文章

  1. bzoj 3786 星系探索 dfs+splay

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

  2. BZOJ 3786 星系探索

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

  3. BZOJ 3786: 星系探索 ETT

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

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

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

  5. BZOJ 3786 星系探索 ——Splay

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

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

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

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

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

  8. 【BZOJ】3786: 星系探索

    [题意]给定一棵带点权树,三种操作: 1.询问点x到根的路径和 2.子树x内的点权加定值y 3.将点x的父亲更换为y,保证仍是树. [算法]平衡树(fhq-treap) [题解] 将树的dfs序作为序 ...

  9. BZOJ 4619 Swap Space 解题报告

    今天是因为David Lee正好讲这个题的类似题,我才做了一下. 本题是world final 2016的一道水…… 题目地址如下 http://www.lydsy.com/JudgeOnline/p ...

随机推荐

  1. phpcms 的模板更换

    刚安装完成后的phpcms ,自带的默认模板样式一般,可以自己换模板 首先打开phpcms文件夹,按照下图路径打开 default是存模板的文件夹 在里面新建一个文件夹 在default中主要用到的是 ...

  2. Windows下使用Python的Curses库时 No module named _curses问题

    这个问题产生的 根本原因 是 curses 库不支持 windows.所以我们在下载完成python后(python 是自带 curses 库的),虽然在  python目录\Lib  中可以看到 c ...

  3. 第七章移动互联网与移动IP

    第七章移动互联网与移动IP 本章延续前几章节,对该章节内容进行归纳总结. 文章中的Why表示产生的背景,也就是说为什么会产生该技术,What表示该技术是什么,How表示该技术是如何使用的.以下将用字母 ...

  4. Java接口获取系统配置信息

    Java获取当前运行系统的配置信息 接口:System.getProperty() 参数 描述 java.version Java运行时环境版本 java.vendor Java运行时环境供应商 ja ...

  5. Red Hat Enterprise Linux / CentOS 7 yum安装zabbix4.0

    添加Zabbix存储库安装存储库配置包. 该软件包包含yum(软件包管理器)配置文件. rpm -ivh https://repo.zabbix.com/zabbix/4.0/rhel/7/x86_6 ...

  6. 福利,一张图看懂IT售前工程师修炼之道

    职场中的新人如何自我定位? 如何深刻理解IT售前这个职位? 如何从IT售前菜鸟成长为IT售前专家? 推荐这本书<IT售前工程师修炼之道> 本书精华内容 售前的重要性 售前要有逻辑能力 售前 ...

  7. C# 钱数 小写 转 大写

    public class Rmb { /// <summary> /// 转换人民币大小金额 /// </summary> /// <param name="n ...

  8. emmmmmm

    211606342杨艺勇 211606379王熙航 单元测试 对每一个代码块进行测试,返回测试结果并和预期结果进行比对 对源代码进行相应的重构,以适应测试代码的调用,且不影响源代码的正常运行 通过与构 ...

  9. 《Linux内核分析》学习总结与学习心得

    一.目录列表 第一周:计算机是如何工作的? http://www.cnblogs.com/dvew/p/5224866.html 第二周:操作系统是如何工作的? http://www.cnblogs. ...

  10. 2018软工实践—Alpha冲刺(7)

    队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭鸭鸭鸭鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作 学习MSI.CUDA 试运行软件并调试 ...