观察
Posted 蒟蒻orz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了观察相关的知识,希望对你有一定的参考价值。
题目大意
给出一颗以 \\(1\\) 为根且有 \\(n\\) 个节点的树,一开始每个节点都是一颗棋子,一面白一面黑,白色的面朝上。
接下来就 \\(q\\) 次操作,操作分两种:
- \\(0\\) 操作,将一颗棋子翻转。
- \\(1\\) 操作,询问一颗棋子与所有面朝上为黑色的棋子的
LCA
最深LCA
的编号(若当前没有黑棋子输出 \\(0\\))。
对于 \\(100 \\%\\) 的数据,\\(1 ≤ n ≤ 800000\\), \\(1 ≤ q ≤ 800000\\)。
解题思路
思路应该算是比较好想的了。
用树状数组或线段树加树剖维护子树内黑色朝上的棋子的个数。
对于操作 \\(0\\),非常简单,不讲了。
对于操作 \\(1\\),每次类似于树剖跳链,不同的是一直跳父亲,判断当前跳到的节点的子树内是否有黑棋,有就直接输出。(这样做的理由是,一个节点与另一个节点的 LCA
只可能存在于两个节点中任意一个节点到根节点的简单路径上)
注意,本题数据过大,可能会爆栈,可以吸氧。
AC CODE
#include <bits/stdc++.h>
#define _ (int)800000 + 5
using namespace std;
int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < \'0\' || c > \'9\')
{
if (c == \'-\')
f = -1;
c = getchar();
}
while (c >= \'0\' && c <= \'9\')
{
x = x * 10 + c - \'0\';
c = getchar();
}
return x * f;
}
int n, m;
int fa[_];
int a[_];
bool tag[_];
int tot, head[_], to[_ << 1], nxt[_ << 1];
int cnt_node, siz[_], dfn[_], hson[_];
void add(int u, int v)
{
to[++tot] = v;
nxt[tot] = head[u];
head[u] = tot;
}
void dfs1(int u)
{
siz[u] = 1;
for (int i = head[u]; i; i = nxt[i])
{
int v = to[i];
if (siz[v])
continue;
dfs1(v);
siz[u] += siz[v];
if (siz[hson[u]] < siz[v])
hson[u] = v;
}
}
void dfs2(int u)
{
dfn[u] = ++cnt_node;
if (!hson[u])
return;
dfs2(hson[u]);
for (int i = head[u]; i; i = nxt[i])
{
int v = to[i];
if (!dfn[v])
dfs2(v);
}
}
void update(int x)
{
int y = 1;
if (tag[x])
y = -1;
tag[x] ^= 1;
for (int i = x; i <= n; i += i & -i)
a[i] += y;
}
int query(int x)
{
int res = 0;
for (int i = x; i > 0; i -= i & -i)
res += a[i];
return res;
}
bool Query(int x)
{
return query(dfn[x] + siz[x] - 1) - query(dfn[x] - 1);
}
int solve(int x)
{
while (x)
{
if (Query(x))
return x;
x = fa[x];
}
return 0;
}
signed main()
{
n = read();
m = read();
for (int i = 2; i <= n; ++i)
{
fa[i] = read();
add(fa[i], i);
add(i, fa[i]);
}
dfs1(1);
dfs2(1);
for (int i = 1; i <= m; ++i)
{
int x;
x = read();
if (x > 0)
{
update(dfn[x]);
}
else
{
printf("%d\\n", solve(-x));
}
}
return 0;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/15228109.html
以上是关于观察的主要内容,如果未能解决你的问题,请参考以下文章