P4332三叉神经树
题面
\(Solution\)
通过模拟,我们会发现每次修改 \(x\),只会改变从 \(x\) 向上一段连续的链的输出。
例如将 \(x\) 点从 \(0\) 改为 \(1,\) 那么它会影响从它向上的一段连续的链,这条链上的每一个节点的 \(1\) 儿子的个数为 \(1(\) 原来都输出 \(0\) ,改完后输出 \(1)\)
\(x\) 从 \(1\) 变 \(0\) 同理
所以我们只需要知道这条链,然后就可以树剖/\(LCT\)去维护。
这里给出 \(LCT\) 解法
记 \(val[x]\) 为 \(x\) 的儿子中 \(1\) 的个数,
那么当修改一个点 \(x\) 从 \(0\) 变 \(1\) 的时候,就成了找从根到 \(x\)的路径上最深的,val不为1的点 \(y\) ,再将 \(y\) 与 \(x\) 拉出一条链,区间修改这颗从 \(x\) 到 \(y\) 的 \(Splay (\)每个点的权值 \(+1)\) , 询问就 \(splay(1)\) ,讨论下 \(val[1]\)
\(x\) 从 \(1\) 变 \(0\) 同理
\(Source\)
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <set>
#include <cstring>
using namespace std;
namespace io {
char buf[1<<21], *pos = buf, *end = buf;
inline char getc()
{ return pos == end && (end = (pos = buf) + fread(buf, 1, 1<<21, stdin), pos == end) ? EOF : *pos ++; }
inline int rint() {
register int x = 0, f = 1; register char c;
while (!isdigit(c = getc())) if (c == '-') f = -1;
while (x = (x << 1) + (x << 3) + (c ^ 48), isdigit(c = getc()));
return x * f;
}
template<typename T>
inline bool chkmin(T &x, T y) { return x > y ? (x = y, 0) : 1; }
template<typename T>
inline bool chkmax(T &x, T y) { return x < y ? (x = y, 0) : 1; }
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define rep(i, a, b) for (register int i = a; i <= b; ++ i)
#define dep(i, a, b) for (register int i = a; i >= b; -- i)
#define travel(i, u) for (register int i = head[u]; i; i = nxt[i])
#define mem(a, b) memset(a, b, sizeof a)
}
using io::rint;
const int N = 1.5e6 + 5;//开三倍,题目要求
int ch[N][3], n, q, fa[N];
struct LCT {
#define ls(x) (ch[x][0])
#define rs(x) (ch[x][1])
#define chk(x) (ch[fa[x]][1] == x)
int ch[N][2], val[N], tag[N], fa[N];
bool not1[N], not2[N];//notx[u]表示以u为根的子树中是否有权值不为x的点,没有为0, 有为1
bool isroot(int x)
{ return ls(fa[x]) ^ x && rs(fa[x]) ^ x; }
void add(int x, int z) {
val[x] += z; tag[x] += z;
if (z > 0) not2[x] = not1[x], not1[x] = 0;
else not1[x] = not2[x], not2[x] = 0;
}
void pushup(int x) {
not1[x] = not1[ls(x)] | not1[rs(x)] | (val[x] != 1);
not2[x] = not2[ls(x)] | not2[rs(x)] | (val[x] != 2);
}
void pushdown(int x) {
if (!tag[x]) return;
if (ls(x)) add(ls(x), tag[x]);
if (rs(x)) add(rs(x), tag[x]);
tag[x] = 0;
}
void rotate(int x) {
int y = fa[x], z = fa[y], k = chk(x), tmp = ch[x][k ^ 1];
ch[y][k] = tmp, fa[tmp] = y;
if (!isroot(y)) ch[z][chk(y)] = x;
fa[x] = z;
ch[x][k ^ 1] = y, fa[y] = x;
pushup(y), pushup(x);
}
int stk[N], top;
void splay(int x) {
stk[top = 1] = x;
for (int i = x; !isroot(i); i = fa[i])
stk[++top] = fa[i];
while (top) pushdown(stk[top--]);
while (!isroot(x)) {
int y = fa[x], z = fa[y];
if (!isroot(y))
if (chk(x) == chk(y)) rotate(y);
else rotate(x);
rotate(x);
}
}
void access(int x) {
for (int y = 0; x; x = fa[y = x])
splay(x), rs(x) = y, pushup(x);
}
int findnot1(int x) {
pushdown(x);
if (!not1[x]) return 0;
if (not1[rs(x)]) return findnot1(rs(x));
if (val[x] != 1) return x;
return findnot1(ls(x));
}
int findnot2(int x) {
pushdown(x);
if (!not2[x]) return 0;
if (not2[rs(x)]) return findnot2(rs(x));
if (val[x] != 2) return x;
return findnot2(ls(x));
}
} T;
void DFS(int x) {
if (x <= n) {
rep (i, 0, 2) {
DFS(ch[x][i]);
T.val[x] += (T.val[ch[x][i]] >> 1);//预处理出每个点的权值
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("P4332.in", "r", stdin);
freopen("P4332.out", "w", stdout);
#endif
n = rint();
rep (i, 1, n) rep (j, 0, 2) {
ch[i][j] = rint();
fa[ch[i][j]] = T.fa[ch[i][j]] = i;
}
rep (i, n + 1, 3 * n + 1) {
T.val[i] = rint(); T.val[i] ++;//很巧妙地计算权值,val存的是儿子中1的个数
}
DFS(1);
q = rint();
while (q --) {
int x = rint();
T.access(x);
T.splay(x);
if (T.val[x] > 1) {//1 - > 0 说明只有2的链才会改变
int y = T.findnot2(T.ch[x][0]);
T.access(fa[y]);
T.splay(x);
T.add(x, -1);
} else {// 0 -> 1 说明只有1的链会改变
int y = T.findnot1(T.ch[x][0]);
T.access(fa[y]);
T.splay(x);
T.add(x, 1);
}
T.splay(1);
printf("%d\n", T.val[1] > 1);
}
}
P4332三叉神经树的更多相关文章
- 【BZOJ-3553】三叉神经树 树链剖分
3553: [Shoi2014]三叉神经树 Time Limit: 160 Sec Memory Limit: 256 MBSubmit: 347 Solved: 112[Submit][Stat ...
- 「SHOI2014」三叉神经树 解题报告
「SHOI2014」三叉神经树 膜拜神仙思路 我们想做一个类似于动态dp的东西,首先得确保我们的运算有一个交换律,这样我们可以把一长串的运算转换成一块一块的放到矩阵上之类的东西,然后拿数据结构维护. ...
- [BZOJ 3553][SHOI2014]三叉神经树
传送门(下面也有题面) 题目大意: 一颗有根树,每个非叶子节点都有三个子节点,每个节点的权为0/1. 每个节点的权 取决于其所有子节点中 哪种权出现的次数更多. 有若干次询问,每次询问修改一个叶子节点 ...
- 三叉神经树 ( neuron )
三叉神经树 ( neuron ) 题目描述 计算神经学作为新兴的交叉学科近些年来一直是学术界的热点.一种叫做SHOI 的神经组织因为其和近日发现的化合物SHTSC 的密切联系引起了人们的极大关注. S ...
- 「SHOI2014」三叉神经树
「SHOI2014」三叉神经树 给你一颗由\(n\)个非叶子结点和\(2n+1\)个叶子结点构成的完全三叉树,每个叶子结点有一个输出:\(0\)或\(1\),每个非叶子结点的输出为自己的叶子结点中较多 ...
- 洛谷P4332 [SHOI2014]三叉神经树(LCT,树剖,二分查找,拓扑排序)
洛谷题目传送门 你谷无题解于是来补一发 随便百度题解,发现了不少诸如树剖\(log^3\)LCT\(log^2\)的可怕描述...... 于是来想想怎么利用题目的性质,把复杂度降下来. 首先,每个点的 ...
- P4332 [SHOI2014]三叉神经树(LCT)
Luogu4332 LOJ2187 题解 代码-Tea 题意 : 每个点有三个儿子 , 给定叶节点的权值\(0\)或\(1\)且支持修改 , 非叶子节点的权值为当有\(>=2\)个儿子的权值为\ ...
- P4332 [SHOI2014]三叉神经树
\(\color{#0066ff}{ 题目描述 }\) 计算神经学作为新兴的交叉学科近些年来一直是学术界的热点.一种叫做SHOI 的神经组织因为其和近日发现的化合物 SHTSC 的密切联系引起了人们的 ...
- 洛谷P4332 [SHOI2014]三叉神经树(LCT)
传送门 FlashHu大佬太强啦%%% 首先,我们可以根据每一个点的权值为$1$的儿子的个数把每个点记为$0~3$,表示这一个点的点权 先考虑一下暴力的过程,假设从$0$变为$1$,先更改一个叶子结点 ...
随机推荐
- 【洛谷P1367】蚂蚁
蚂蚁 [题目描述] 在一根无限长的木棍上,用n只蚂蚁,每只蚂蚁有一个初始位置和初始朝向,蚂蚁们以每秒一个单位的速度向前移动,当两只蚂蚁相遇时,它们会掉头(掉头时间忽略不计).现给出每只蚂蚁的初始位置和 ...
- 【luogu P2024 食物链】 题解
题目链接:https://www.luogu.org/problemnew/show/P2024 摘吊打集训队的九日dalao一句话 关于带有多个相对集合的全集,我们可以多开几倍的空间.每一倍的元素表 ...
- AngularJS表格排序
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- sharepoint2013配置开发环境
- vue进阶语法及生命周期函数
1.calss和style绑定 操作元素的 class 列表和内联样式style是数据绑定的一个常见需求,它两都是属性,所以可以通过v-bind来绑定 1.1绑定HTML class 可以给v-bin ...
- JDBC连接数据库时错误提示的解决方案汇总
今天在连接JDBC时,出现了错误 最开始的URL是这样写的 Connection conn = DriverManager.getConnection("jdbc:mysql://local ...
- ATK系列库介绍
1.一个完整支持分布式服务框架: 2.代码生成工具,可快速生成基于服务框架的应用: 3.其他支持库 4.完整代码见https://github.com/azthinker 目标:使应用开发,低代码.高 ...
- update、commit、trancate,delete
update 用于更新表的数据,使用方式为: update table_name set column_name=值 条件 顺便一提:date数据插入更新应该使用 to_date()格式转换函数例如: ...
- Lucas定理及应用
额,前两天刚讲了数据结构,今天我来讲讲组合数学中的一种奇妙优化——Lucas 先看这样一个东西 没学过lucas的肯定会说:还不简单?处理逆元,边乘边膜呗 是,可以,但注意一下数据范围 你算这一次,你 ...
- Java中抽象类与接口的比较
一.基本概念 抽象类:表示这个对象是什么:比如 男人.女人这两个类,他们的抽象类是人,说明男人.女人是人: 接口:表示这个对象能做什么:比如人可以吃东西,狗也可以吃东西,将“吃东西”定义为一个接口,让 ...