bzoj3786
splay维护dfs序
我们发现有移动子树这种操作,树剖是做不了了,又要实现子树加,lct又维护不了了,这时我们用splay维护入栈出栈序来支持这些操作。我们记录每个点的入栈时间和出栈时间,这样一个闭合的区间就表示了一个节点的子树,于是我们可以支持更换父亲了。然后是子树加,这里我们把要加的区间提取出来,打标记,但是我们还得维护一个符号总和,因为入栈时间加,出栈时间要减去加的值,因为出栈时间之后得序列就不属于这棵子树了。最后是查询,查询我们只要把查询节点的入栈时间和1号节点提取出来,然后总和就是答案。注意提取区间时不是in[x]-1,out[x]+1,虽然这里节点编号就是对应排名,但是因为这里是出栈入栈序,所以+1-1不一定是序列中下一个节点,所以我们要查询前继后继,也就是提取pre(in[x])和nxt(out[x])
然后还卡时间,我用fread卡过去了
#include<bits/stdc++.h>
using namespace std;
const int N = , Maxlen = * N;
int n, m, dfs_clock = , root;
int in[N], out[N];
long long w[N];
vector<int> G[N];
char buf[Maxlen], *C = buf;
int Len;
inline int read()
{
int x = ;
while (*C < '' || '' < *C) ++C;
while ('' <= *C && *C <= '') x = x * + *C - '', ++C;
return x;
}
namespace Splay_tree
{
int cnt;
int child[N][], fa[N], st[N];
long long sum[N], key[N], tag[N], tim[N], sum_tim[N];
inline bool wh(int x)
{
return child[fa[x]][] == x;
}
inline void update(int x)
{
sum[x] = sum[child[x][]] + sum[child[x][]] + key[x];
sum_tim[x] = sum_tim[child[x][]] + sum_tim[child[x][]] + tim[x];
}
inline void pushdown(int x)
{
if(tag[x] == ) return;
tag[child[x][]] += tag[x];
tag[child[x][]] += tag[x];
key[child[x][]] += tag[x] * tim[child[x][]];
key[child[x][]] += tag[x] * tim[child[x][]];
sum[child[x][]] += tag[x] * sum_tim[child[x][]];
sum[child[x][]] += tag[x] * sum_tim[child[x][]];
tag[x] = ;
}
inline void rotate(int x)
{
int y = fa[x], z = fa[y], t = wh(x);
fa[x] = z;
child[z][wh(y)] = x;
child[y][t] = child[x][t ^ ];
fa[child[x][t ^ ]] = y;
child[x][t ^ ] = y;
fa[y] = x;
update(y);
update(x);
}
inline void up(int x)
{
int top = , now = x;
while(now != root)
{
st[++top] = now;
now = fa[now];
}
st[++top] = root;
for(int i = top; i; --i) pushdown(st[i]);
}
inline void splay(int x, int t)
{
up(x);
for(int f; (f = fa[x]) != t; rotate(x))
if(fa[f] != t) rotate(wh(x) == wh(f) ? f : x);
if(!t) root = x;
}
inline void build(int l, int r, int &x, int last)
{
if(l > r) return;
int mid = (l + r) >> ;
x = mid;
fa[x] = last;
build(l, mid - , child[x][], x);
build(mid + , r, child[x][], x);
update(x);
}
inline int pre(int x)
{
splay(x, );
x = child[x][];
while(child[x][]) x = child[x][];
return x;
}
inline int nxt(int x)
{
splay(x, );
x = child[x][];
while(child[x][]) x = child[x][];
return x;
}
inline void change(int x, int y)
{
int a = pre(in[x]), b = nxt(out[x]);
splay(a, );
splay(b, root);
int t = child[child[root][]][];
fa[t] = child[child[root][]][] = ;
update(child[root][]);
update(root);
a = nxt(in[y]);
splay(in[y], );
splay(a, root);
fa[t] = child[root][];
child[child[root][]][] = t;
update(child[root][]);
update(root);
}
inline void ask(int x)
{
x = nxt(in[x]);
splay(, );
splay(x, root);
int t = child[child[root][]][];
printf("%lld\n", sum[t]);
}
inline void add(int x, int delta)
{
int a = pre(in[x]), b = nxt(out[x]);
splay(a, );
splay(b, root);
int t = child[child[root][]][];
tag[t] += delta;
sum[t] += delta * sum_tim[t];
key[t] += delta * tim[t];
}
} using namespace Splay_tree;
void dfs(int u)
{
in[u] = ++dfs_clock;
tim[in[u]] = ;
key[in[u]] = w[u];
for(int i = ; i < G[u].size(); ++i)
{
int v = G[u][i];
dfs(v);
}
out[u] = ++dfs_clock;
key[out[u]] = -w[u];
tim[out[u]] = -;
}
int main()
{
// freopen("galaxy20.in", "r", stdin);
// freopen("output.txt", "w", stdout);
Len = fread(C, , Maxlen, stdin);
buf[Len] = '\0';
n = read();
for(int i = ; i <= n; ++i)
{
int u = read();
G[u].push_back(i);
}
for(int i = ; i <= n; ++i) w[i] = read();
dfs();
++dfs_clock;
build(, dfs_clock, root, );
m = read();
while(m--)
{
char c;
int x, y;
for(c = *C; c < 'A' || c > 'Z'; ++C, c = *C);
if(c == 'Q')
{
x = read();
ask(x);
}
if(c == 'C')
{
x = read();
y = read();
change(x, y);
}
if(c == 'F')
{
x = read();
y = read();
add(x, y);
}
}
// fclose(stdin);
// fclose(stdout);
return ;
}
bzoj3786的更多相关文章
- [BZOJ3786]星系探索
[BZOJ3786]星系探索 试题描述 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个 ...
- 【BZOJ3786】星系探索 DFS序+Splay
[BZOJ3786]星系探索 Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球 ...
- BZOJ3786 星系探索 【Splay维护dfs序】*
BZOJ3786 星系探索 Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均 ...
- [BZOJ3786]星系探索(伪ETT)
3786: 星系探索 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1638 Solved: 506[Submit][Status][Discuss ...
- BZOJ3786 星际探索
@(BZOJ)[DFS序, Splay] Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其 ...
- [BZOJ3786] 星系探索(括号序列+Splay)
3786: 星系探索 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 2191 Solved: 644[Submit][Status][Discuss ...
- 【BZOJ-3786】星系探索 Splay + DFS序
3786: 星系探索 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 647 Solved: 212[Submit][Status][Discuss] ...
- bzoj3786星系探索 splay
3786: 星系探索 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1314 Solved: 425[Submit][Status][Discuss ...
- BZOJ3786星系探索——非旋转treap(平衡树动态维护dfs序)
题目描述 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球没有依赖星球. ...
- BZOJ3786: 星系探索 Splay+DFS序
题目大意:给你一个树,支持三种操作,子树加,点到根的路径和,改变某一个点的父亲. 分析: 看起来像一个大LCT,但是很显然,LCT做子树加我不太会啊... 那么,考虑更换一个点的父亲这个操作很有意思, ...
随机推荐
- ubuntu 14.04上源码编译安装php7
wget https://downloads.php.net/~ab/php-7.0.0alpha2.tar.bz2 //用winscp把下载好的文件上传到网站中 tar jxf php-7.0.0a ...
- element-UI 多表单重置的时候的坑
问题细化一下是这样的:比如我有一个用来修改数据的表单,第一条数据是{name: 'Xixi', age: 12},打开表单后就有两个输入框分别填的是Xixi和12,此时我修改Xixi为Haha,调用t ...
- Python接口测试之unittest框架(五)
Test-driven development(TDD)开发模式在今天已经不是什么新奇的事了,它的开发思维是在开发一个产品功能的时候,先 编写好该功能的测试代码,在编写开发比如,比如要写二个数相除的函 ...
- C语言学习<输入输出函数,函数的调用>
#include <stdio.h> /* 输入输出函数的学习 函数的调用 2017.05.25 soulsjie */ //输入连个数字求最大值 void main(){ int Max ...
- HDU-5583-Kingdom of Black and White(2015ACM/ICPC亚洲区上海站-重现赛)
Kingdom of Black and White ...
- GitHub & puppeteer & Chinese character & bug
GitHub & puppeteer & Chinese character & bug https://github.com/GoogleChrome/puppeteer/b ...
- [luoguP1015] 回文数(模拟 + 高精度?)
传送门 类似高精的操作... 代码 #include <cstdio> #include <cstring> #include <iostream> #define ...
- Eclipse4.5在线安装Aptana插件及配置代码提示教程
一.Aptana插件官网地址 我在网上试过登陆到aptana官网后点击下载,选择下载eclipse插件版,然后页面给出一串地址:http://download.aptana.com/s ...
- [NOIP2005] 提高组 洛谷P1051 谁拿了最多奖学金
题目描述 某校的惯例是在每学期的期末考试之后发放奖学金.发放的奖学金共有五种,获取的条件各自不同: 1) 院士奖学金,每人8000元,期末平均成绩高于80分(>80),并且在本学期内发表1篇或1 ...
- PHP_pear的安装和使用
-------------- 安装pear -------------- pear是PHP的扩展和应用程序库,包含了很多有用的类,安装好php5.0后,pear实际上并没有被安装 ...