BZOJ3786 星际探索
@(BZOJ)[DFS序, Splay]
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\). 保证操作合法.
Solution
splay tree维护DFN序.
#include <cstdio>
#include <cctype>
#include <cstring>
const int N = 1 << 17, M = 1 << 19;
int L[N], R[N];
namespace Zeonfai
{
inline int getInt()
{
int a = 0, sgn = 1;
char c;
while(! isdigit(c = getchar()))
if(c == '-')
sgn *= -1;
while(isdigit(c))
a = a * 10 + c - '0', c = getchar();
return a * sgn;
}
inline char getChar()
{
char c;
while(! isgraph(c = getchar()));
return c;
}
}
struct tree
{
int head[N], top;
struct edge
{
int v, nxt;
}edg[M];
inline void init()
{
memset(head, -1, sizeof(head));
top = 0;
}
inline void addEdge(int u, int v)
{
edg[top].v = v, edg[top].nxt = head[u];
head[u] = top ++;
}
int clk;
void DFS(int u)
{
L[u] = clk ++;
for(int i = head[u]; ~ i; i = edg[i].nxt)
DFS(edg[i].v);
R[u] = clk ++;
}
}org;
struct splayTree
{
struct node
{
int suc[2], pre;
long long w, sgn, sum, tag, sz;
inline node()
{
sz = w = sgn = sum = tag = 0;
pre = suc[0] = suc[1] = -1;
}
}nd[N << 1];
inline void update(int u)
{
nd[u].sum = nd[u].w * nd[u].sgn;
nd[u].sz = nd[u].sgn;
if(~ nd[u].suc[0])
nd[u].sum += nd[nd[u].suc[0]].sum, nd[u].sz += nd[nd[u].suc[0]].sz;
if(~ nd[u].suc[1])
nd[u].sum += nd[nd[u].suc[1]].sum, nd[u].sz += nd[nd[u].suc[1]].sz;
}
int root;
int build(int L, int R, int pre)
{
if(L > R)
return -1;
int mid = L + R >> 1;
nd[mid].pre = pre;
nd[mid].suc[0] = build(L, mid - 1, mid);
nd[mid].suc[1] = build(mid + 1, R, mid);
update(mid);
return mid;
}
inline void pushdown(int u)
{
if(nd[u].pre != -1)
pushdown(nd[u].pre);
if(~ nd[u].suc[0])
nd[nd[u].suc[0]].tag += nd[u].tag, nd[nd[u].suc[0]].w += nd[u].tag, nd[nd[u].suc[0]].sum += nd[u].tag * nd[nd[u].suc[0]].sz;
if(~ nd[u].suc[1])
nd[nd[u].suc[1]].tag += nd[u].tag, nd[nd[u].suc[1]].w += nd[u].tag, nd[nd[u].suc[1]].sum += nd[u].tag * nd[nd[u].suc[1]].sz;
nd[u].tag = 0;
}
inline int getRelation(int u)
{
if(nd[u].pre == -1)
return -1;
return u == nd[nd[u].pre].suc[1];
}
inline void rotate(int u)
{
int pre = nd[u].pre, prepre = nd[pre].pre, k = getRelation(u);
if(~ nd[u].suc[k ^ 1])
nd[nd[u].suc[k ^ 1]].pre = pre;
nd[pre].suc[k] = nd[u].suc[k ^ 1];
nd[u].suc[k ^ 1] = pre;
nd[u].pre = prepre;
if(~ prepre)
nd[prepre].suc[getRelation(pre)] = u;
nd[pre].pre = u;
update(pre), update(u);
}
inline void splay(int u, int bnd)
{
pushdown(u);
while(nd[u].pre != bnd)
{
int pre = nd[u].pre;
if(nd[pre].pre != bnd)
rotate(getRelation(u) == getRelation(pre) ? pre : u);
rotate(u);
}
}
inline int getLast(int u)
{
splay(u, -1);
u = nd[u].suc[0];
while(~ nd[u].suc[1])
u = nd[u].suc[1];
return u;
}
inline int getNext(int u)
{
splay(u, -1);
u = nd[u].suc[1];
while(~ nd[u].suc[0])
u = nd[u].suc[0];
return u;
}
}seq;
int main()
{
#ifndef ONLINE_JUDGE
freopen("BZOJ3786.in", "r", stdin);
freopen("BZOJ3786.out", "w", stdout);
#endif
using namespace Zeonfai;
int n = getInt();
org.init();
for(int i = 2; i <= n; ++ i)
{
int pre = getInt();
org.addEdge(pre, i);
}
org.clk = 1;
org.DFS(1);
for(int i = 1; i <= n; ++ i)
{
int w = getInt();
seq.nd[L[i]].w = seq.nd[R[i]].w = w;
seq.nd[L[i]].sgn = 1, seq.nd[R[i]].sgn = -1;
}
seq.root = seq.build(0, org.clk, -1);
int m = getInt();
for(int i = 0; i < m; ++ i)
{
char opt = getChar();
if(opt == 'Q')
{
int u = getInt();
seq.splay(L[u], -1);
printf("%lld\n", seq.nd[seq.nd[L[u]].suc[0]].sum + seq.nd[L[u]].w);
}
else if(opt == 'C')
{
int u = getInt(), v = getInt();
int lst = seq.getLast(L[u]), nxt = seq.getNext(R[u]);
seq.splay(lst, -1);
seq.splay(nxt, lst);
int tmp = seq.nd[nxt].suc[0];
seq.nd[nxt].suc[0] = -1;
seq.update(nxt);
lst = L[v];
nxt = seq.getNext(L[v]);
seq.splay(lst, -1);
seq.splay(nxt, lst);
seq.nd[tmp].pre = nxt;
seq.nd[nxt].suc[0] = tmp;
seq.update(nxt);
}
else if(opt == 'F')
{
int u = getInt(), inc = getInt();
int lst = seq.getLast(L[u]), nxt = seq.getNext(R[u]);
seq.splay(lst, -1);
seq.splay(nxt, lst);
seq.nd[seq.nd[nxt].suc[0]].tag += inc;
seq.nd[seq.nd[nxt].suc[0]].sum += seq.nd[seq.nd[nxt].suc[0]].sz * inc;
seq.nd[seq.nd[nxt].suc[0]].w += inc;
}
}
}
BZOJ3786 星际探索的更多相关文章
- bzoj3786 星际探索 splay dfs序
这道题 首先 因为他求的是当前点到根节点的路径和 我们可以将题目转换为括号序列的写法 将点拆为左括号以及右括号 左括号为正 右括号为负 这样题目就变为了求前缀和了 如果一个点是这个点的子树 那么他的左 ...
- [BZOJ3786]星系探索
[BZOJ3786]星系探索 试题描述 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个 ...
- 牛客 小a与星际探索 bfs
链接:https://ac.nowcoder.com/acm/contest/317/C?&headNav=acm来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ ...
- 小a与星际探索
链接:https://ac.nowcoder.com/acm/contest/317/C来源:牛客网 小a正在玩一款星际探索游戏,小a需要驾驶着飞船从11号星球出发前往nn号星球.其中每个星球有一个能 ...
- BZOJ3786 星系探索 【Splay维护dfs序】*
BZOJ3786 星系探索 Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均 ...
- 小a与星际探索---DP
题目描述 小a正在玩一款星际探索游戏,小a需要驾驶着飞船从11号星球出发前往nn号星球.其中每个星球有一个能量指数pp.星球ii能到达星球jj当且仅当pi>pjpi>pj.同时小a的飞船还 ...
- 牛客 小a与星际探索
链接:https://ac.nowcoder.com/acm/contest/317/C来源:牛客网 小a正在玩一款星际探索游戏,小a需要驾驶着飞船从1号星球出发前往n号星球.其中每个星球有一个能量指 ...
- [BZOJ3786]星系探索(伪ETT)
3786: 星系探索 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1638 Solved: 506[Submit][Status][Discuss ...
- [BZOJ3786] 星系探索(括号序列+Splay)
3786: 星系探索 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 2191 Solved: 644[Submit][Status][Discuss ...
随机推荐
- js获取主机名实现页面跳转
<script language="javascript" type="text/javascript"> var hostname ...
- 更改ubuntu的官方镜像源
我们自己安装的ubuntu通常默认镜像源是官方的,并不好用,因为网速以及限制比较多,所以为了使用方便,通常都会去更改一下默认的镜像源配置. 这里我们使用清华大学开源镜像软件站,https://mirr ...
- verilog behavioral modeling--overview
1.verilog behavioral models contain procedural statements that control the simulation and manipulate ...
- bs4--官文--修改文档树
修改文档树 Beautiful Soup的强项是文档树的搜索,但同时也可以方便的修改文档树 修改tag的名称和属性 在 Attributes 的章节中已经介绍过这个功能,但是再看一遍也无妨. 重命名一 ...
- 10大mysql需要注意的参数
MySQL变量很多,其中有一些MySQL变量非常值得我们注意,下面就为您介绍一些值得我们重点学习的MySQL变量,供您参考. 1 Threads_connected 首先需要注意的,想得到这个变量的值 ...
- BZOJ 2508: 简单题
题目大意: 加入直线,删除直线,求点到所有直线的距离的平方和. 题解: 把点到直线的距离公式写出来,然后展开.维护六个值,计算一个二元的多项式的最小值. 对x和y分别求导,导数都为零时取到极值.然后解 ...
- Spark——为数据分析处理提供更为灵活的赋能
本文来自网易云社区 作者:王佳楠 一.概述 现如今在大规模数据处理分析的技术领域中,Hadoop及其生态内的各功能组件占据了绝对的统治地位.Hadoop原生的MapReduce计算框架由于任务抽象简单 ...
- xfce-OpenVAS
OpenVAS开源风险评估系统部署方案 OpenVAS,即开放式漏洞评估系统,是一个用于评估目标漏洞的杰出框架.功能十分强大,最重要的是,它是“开源”的——就是免费的意思啦- 它与著名的Nessu ...
- 信息安全试验-DES加密!
信息安全试验二--DES加密算法 本渣表示没有理解原理,照着书上敲了一发,运行无误! 吐槽:手动S盒简直丧心病狂,扩展置换表全是手动输入,加密原理还是很好理解,两次异或,先混淆. 此代码数据由老师给出 ...
- 九度oj 题目1499:项目安排
题目描述: 小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时间,假设做完每个项目后,拿到报酬都是不同的.由于小明马上就要硕士毕业了,面临着买房.买车.给 ...