首页 > 其他分享 >E. Chain Queries

E. Chain Queries

时间:2024-05-29 21:33:02浏览次数:25  
标签:黑色 Chain int ++ -- Queries 节点 color

E. Chain Queries

You are given a tree of $n$ vertices numbered from $1$ to $n$. Initially, all vertices are colored white or black.

You are asked to perform $q$ queries:

  • "u" — toggle the color of vertex $u$ (if it was white, change it to black and vice versa).

After each query, you should answer whether all the black vertices form a chain. That is, there exist two black vertices such that the simple path between them passes through all the black vertices and only the black vertices. Specifically, if there is only one black vertex, they form a chain. If there are no black vertices, they do not form a chain.

Input

Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1\leq t\leq 10^4$). The description of the test cases follows.

The first line of each test case contains two integers $n$ and $q$ ($1\leq n,q\leq 2\cdot 10^5$).

The second line of each test case contains $n$ integers $c_1,c_2,\ldots,c_n$ ($c_i \in \{ \mathtt{0}, \mathtt{1} \}$) — the initial color of the vertices. $c_i$ denotes the color of vertex $i$ where $\mathtt{0}$ denotes the color white, and $\mathtt{1}$ denotes the color black.

Then $n - 1$ lines follow, each line contains two integers $x_i$ and $y_i$ ($1 \le x_i,y_i \le n$), indicating an edge between vertices $x_i$ and $y_i$. It is guaranteed that these edges form a tree.

The following $q$ lines each contain an integer $u_i$ ($1 \le u_i \le n$), indicating the color of vertex $u_i$ needs to be toggled.

It is guaranteed that the sum of $n$ and $q$ over all test cases respectively does not exceed $2\cdot 10^5$.

Output

For each query, output "Yes" if the black vertices form a chain, and output "No" otherwise.

You can output "Yes" and "No" in any case (for example, strings "yEs", "yes", "Yes" and "YES" will be recognized as a positive response).

Examples

input

2
2 1
1 0
1 2
1
5 4
1 0 0 0 0
1 2
1 3
1 5
3 4
4
3
2
5

output

No
No
Yes
Yes
No

Note

In the second test case, the color of the vertices are as follows:

The initial tree:

The first query toggles the color of vertex $4$:

The second query toggles the color of vertex $3$:

The third query toggles the color of vertex $2$:

The fourth query toggles the color of vertex $5$:

 

解题思路

  把节点 $1$ 固定为树根,并规定节点 $1$ 的父节点为始终是白色的节点 $0$。如果树中只存在一条由黑色节点构成的链,只可能是以下两种形式:

  若左边的情况要成立,必然满足以下 $2$ 个条件:

  1. 每个节点最多只有一个黑色儿子。
  2. 在所有的黑色节点中,有且只有一个黑色节点的父节点是白色。

  若右边的情况要成立,必然满足以下 $2$ 个条件:

  1. 必然有一个黑色节点有恰好两个黑色儿子,其余节点最多只有一个黑色儿子。
  2. 在所有的黑色节点中,有且只有一个黑色节点的父节点是白色,且这个节点就是恰好两个黑色儿子的黑色节点。

  为此我们维护以下信息。$p_u$ 表示节点 $u$ 的父节点;$s_u$ 表示节点 $u$ 黑色儿子的数量;$c_2$ 表示有恰好两个黑色儿子的节点数量;$c_3$ 表示有超过两个黑色儿子的节点数量;$f$ 表示在所有的黑色节点中父节点是白色的黑色节点数量;同时开一个 std::set 存储恰好两个黑色儿子的节点编号。考虑每次修改如何维护这些信息。

  如果节点 $u$ 从黑色变白色:$u$ 的儿子会对 $f$ 有影响,有 $f \gets f + s_u$。$p_u$ 也对 $f$ 有影响,有 $f \gets f - [c_{p_u} = 0]$。$p_u$ 对 $s_{p_u}$,$c_2$,$c_3$ 有影响,为了方便用代码来表示:

if (s[p] == 2) c2--, st.erase(p);
else if (s[p] > 2) c3--;
s[p]--;
if (s[p] == 2) c2++, st.insert(p);
else if (s[p] > 2) c3++;

  同理节点 $x$ 从白色变黑色,只需将一些加法操作改为减法,具体可见代码。

  最后对于每个询问,如果以下条件有一个成立,都不会存在恰好一条由黑色节点构成的链,否则存在。

  1. 某个节点有 $3$ 个及以上的黑色儿子,即 $c_3 > 0$。
  2. 树中不存在黑色节点,或至少有两条链,即 $f \ne 1$。
  3. 有两个黑色儿子的节点不止一个,即 $c_2 > 1$。
  4. $c_2 = 1$,但这个节点不是黑色或这个节点的父节点不是白色。

  AC 代码如下,时间复杂度为 $O(n+q)$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 2e5 + 5, M = N * 2;

int c[N];
int h[N], e[M], ne[M], idx;
int fa[N], s[N];

void add(int u, int v) {
    e[idx] = v, ne[idx] = h[u], h[u] = idx++;
}

void dfs(int u, int p) {
    fa[u] = p;
    s[u] = 0;
    for (int i = h[u]; i != -1; i = ne[i]) {
        int v = e[i];
        if (v == p) continue;
        s[u] += c[v];
        dfs(v, u);
    }
}

void solve() {
    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%d", c + i);
    }
    idx = 0;
    memset(h, -1, n + 1 << 2);
    for (int i = 0; i < n - 1; i++) {
        int u, v;
        scanf("%d %d", &u, &v);
        add(u, v), add(v, u);
    }
    dfs(1, 0);
    int c2 = 0, c3 = 0, f = 0;
    set<int> st;
    for (int i = 1; i <= n; i++) {
        if (s[i] == 2) c2++, st.insert(i);
        else if (s[i] > 2) c3++;
        if (c[i] && !c[fa[i]]) f++;
    }
    while (m--) {
        int x;
        scanf("%d", &x);
        if (c[x]) {
            f += s[x];
            int p = fa[x];
            if (!c[p]) f--;
            if (p) {
                if (s[p] == 2) c2--, st.erase(p);
                else if (s[p] > 2) c3--;
                s[p]--;
                if (s[p] == 2) c2++, st.insert(p);
                else if (s[p] > 2) c3++;
            }
        }
        else {
            f -= s[x];
            int p = fa[x];
            if (!c[p]) f++;
            if (p) {
                if (s[p] == 2) c2--, st.erase(p);
                else if (s[p] > 2) c3--;
                s[p]++;
                if (s[p] == 2) c2++, st.insert(p);
                else if (s[p] > 2) c3++;
            }
        }
        c[x] ^= 1;
        if (c3 || f != 1 || c2 > 1 || c2 == 1 && c[fa[*st.begin()]]) printf("NO\n");
        else printf("YES\n");
    }
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        solve();
    }
    
    return 0;
}

 

参考资料

  Codeforces Round #947 Editorial:https://codeforces.com/blog/entry/129801

标签:黑色,Chain,int,++,--,Queries,节点,color
From: https://www.cnblogs.com/onlyblues/p/18221108

相关文章

  • Hugging Face x LangChain: 全新 LangChain 合作伙伴包
    我们很高兴官宣发布langchain_huggingface,这是一个由HuggingFace和LangChain共同维护的LangChain合作伙伴包。这个新的Python包旨在将HuggingFace最新功能引入LangChain并保持同步。源自社区,服务社区目前,LangChain中所有与HuggingFace相关的类都是由社区贡......
  • 一起学习大模型 - langchain里的 PromptTemplate详细介绍
    文章目录前言一、安装LangChain二、基本用法1.导入库并定义模板2.填充模板三、进阶用法1.使用多个变量2.嵌套模板3.动态变量四、应用模板与大模型交互五、疑问解答1.举例说明2.更详细的例子总结前言上一篇文章我们讲了Prompt的概念和作用(大模型的交......
  • Vitis HLS 学习笔记--块级控制协议-ap_ctrl_chain/ap_ctrl_hs/ap_ctrl_none
    目录1.简介2.详细分析2.1使用场景区别2.2 ap_continue行为详解2.3 ap_ctrl_chain行为详解3.总结1.简介块级控制协议允许硬件模块表明:何时可以开始处理数据。何时完成了数据处理。以及何时处于空闲状态,准备接受新的数据输入。这些信号用于本模块在与其他硬......
  • 5分钟明白LangChain 的输出解析器和链
    本文介绍LangChain的输出解析器OutputParser的使用,和基于LangChain的LCEL构建链。1.输出解析器OutputParser1.1、为什么需要OutputParser常规的使用LangChain构建LLM应用的流程是:Prompt输入、调用LLM、LLM输出。有时候我们期望LLM给到的数据是格式化的数据,方便做后续的处......
  • AI菜鸟向前飞 — LangChain系列之十四 - Agent系列:从现象看机制(上篇)
    上一篇介绍了Agent与LangGraph的基础技能Tool的必知必会AI菜鸟向前飞—LangChain系列之十三-关于Tool的必知必会前面已经详细介绍了Prompt、RAG,终于来到Agent系列(别急后面还有LangGraph),大家可以先看下这张图:   看完我这系列就都懂了:)牛刀初试    由于本篇是入......
  • AI菜鸟向前飞 — LangChain系列之十二 - RAG(下篇):Index和Retriever
    AI菜鸟向前飞—LangChain系列之十-RAG(上篇)AI菜鸟向前飞—LangChain系列之十一-RAG(中篇)先分享个问题的解法#在使用Chroma实例化过程中,可能会出现如下报错AttributeError:typeobject'hnswlib.Index'hasnoattribute'file_handle_count'当使用代码遇到如上问......
  • Codeforces Round 947 (Div. 1 + Div. 2) E. Chain Queries
    本来决定开摆养生不打的,但11点半的时候点进去看到这个题是个疑似DS,写题的欲望瞬间高涨,然后就40min写了这个题然而赛中并不能提交,只好等到第二天早上再交一发,没想到还WA了一发才过首先这题如果我们能确定当前黑色点集的链的两个端点\(x,y\)的话,这个题就非常显然了只需要求出\((x......
  • 大模型开发:第一批用 LangChain 的程序员,早就已经碾压同事了。。
    今年招聘市场确实是好点了,我发现群友都在讨论,得赶快学点AI大模型。他们有的是想正式转到一些新兴的AI行业,需要系统的学习训练。更多的是想跟已有的技能结合,辅助编程提效,或上手实操应用,增加自己的职场竞争力。这也可以理解,ChatGPT推出仅一年半的时间,就将生成式AI推......
  • 【智应数】Markow chains
    MarkowChain&StationaryDistributionDef(FiniteMarkowChain).Let\(\Omega\)beafinitesetofstates,\(\forallx,y\in\Omega,P(x,y)\ge0\)beatransitionfunction,i.e.,\(\sum\limits_{y\in\Omega}P(x,y)=1.\)AfiniteMarkowchain......
  • CF1973F Maximum GCD Sum Queries 题解
    题目链接点击打开链接题目解法首先想到枚举两个数列的$\gcd$,求最小代价两个数列的\(\gcd\)应该分别是\(a_1,b_1\)的因数或\(b_1,a_1\)的因数这样就把枚举范围缩小到了\(d(a_1)\timesd(b_1)\),这求最小代价需要\(O(n)\),不够快假设枚举的\(\gcd\)分别为\(x,y\)......