Codeforces 343D Water Tree

题意简述

维护一棵树,支持以下操作:

  • 0 v:将以v为跟的子树赋值为1
  • 1 v:将v到根节点的路径赋值为0
  • 2 v:询问v的值

题解思路

树剖+珂朵莉树

代码

#include <set>
#include <cstdio>
#define IT std::set<Node>::iterator
const int N=500005;
int n,q,u,v,opt,x,cnt;
int h[N],to[N<<1],nxt[N<<1];
int fa[N],sz[N],hvs[N],id[N],top[N];
struct Node {
    int l,r; bool v;
    Node(const int& L,const int& R=-1,const bool& V=0):l(L),r(R),v(V) {}
    bool operator <(const Node& x) const { return l<x.l; }
};
inline void add_edge(const int& u,const int& v) {
    to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt;
}
void dfs1(const int& u) {
    sz[u]=1;
    for (register int i=h[u];i;i=nxt[i])
        if (to[i]^fa[u]) {
            fa[to[i]]=u;
            dfs1(to[i]);
            sz[u]+=sz[to[i]];
            if (sz[to[i]]>sz[hvs[u]]) hvs[u]=to[i];
        }
}
void dfs2(const int& u) {
    id[u]=++cnt;
    if (hvs[u]) { top[hvs[u]]=top[u]; dfs2(hvs[u]); }
    for (register int i=h[u];i;i=nxt[i])
        if (to[i]!=hvs[u]&&to[i]!=fa[u]) {
            top[to[i]]=to[i]; dfs2(to[i]);
        }
}
std::set<Node> s;
inline IT split(const int& pos) {
    IT it=s.lower_bound(Node(pos,0,0));
    if (it!=s.end()&&it->l==pos) return it;
    --it;
    const int L=it->l,R=it->r; const bool V=it->v;
    s.erase(it);
    s.insert(Node(L,pos-1,V)); return s.insert(Node(pos,R,V)).first;
}
inline void assign(const int& l,const int& r,const bool& va) {
    IT itr=split(r+1),itl=split(l); s.erase(itl,itr); s.insert(Node(l,r,va));
}
inline void modify(int u) {
    for (;top[u]!=1;u=fa[top[u]]) assign(id[top[u]],id[u],0); assign(1,id[u],0);
}
inline int query(int x) { IT it=split(x); return it->v; }
int main() {
    scanf("%d",&n); s.insert(Node(1,n,0));
    for (register int i=1;i<n;++i)
        scanf("%d%d",&u,&v),add_edge(u,v),add_edge(v,u);
    cnt=0; fa[1]=top[1]=1; dfs1(1); dfs2(1);
    scanf("%d",&q);
    for (register int i=1;i<=q;++i) {
        scanf("%d%d",&opt,&x);
        if (opt==1) assign(id[x],id[x]+sz[x]-1,1);
        else if (opt==2) modify(x);
        else printf("%d\n",query(id[x]));
    }
}

原文地址:https://www.cnblogs.com/xuyixuan/p/11360918.html

时间: 2024-07-31 05:35:25

Codeforces 343D Water Tree的相关文章

Codeforces 343D Water Tree(DFS序+线段树+技巧)

题目链接:http://codeforces.com/problemset/problem/343/D 题目: Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a reservoir which can be either empty or filled with water. The vertices of the tree are numbered f

CodeForces 343D water tree(树链剖分)

Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a reservoir which can be either empty or filled with water. The vertices of the tree are numbered from 1 to n with the root at vertex 1. For each vertex, t

codeforces 343D Water Tree 树链剖分 dfs序 线段树 set

题目链接 这道题主要是要考虑到同一棵子树中dfs序是连续的 然后我就直接上树剖了... 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAXN=600005; 4 5 struct Node 6 { 7 int l,r; 8 int value; 9 void init() 10 { 11 l=r=value=0; 12 } 13 }tree[4*MAXN]; 14 vector<int>nei[MAXN]

Codeforces 343D Water Tree & 树链剖分教程

原题链接 题目大意 给定一棵根为1,初始时所有节点值为0的树,进行以下三个操作: 将以某点为根的子树节点值都变为1 将某个节点及其祖先的值都变为0 *询问某个节点的值 解题思路 这是一道裸的树链剖分题.下面详细地介绍一下树链剖分. 树链剖分预备知识: 线段树.DFS序 树链剖分想法|起源 首先,如果一棵树退化成一条链,那么它会有非常好的性质.我们可以用线段树等数据结构来维护相关操作,使得效率更高.那么我们考虑一般的树,它是否能被分成一些链,使它们也能更高效地进行某些操作? 算法流程 以下以点带权

【CodeForces】343D Water tree (线段树好题!还未弄懂)

/* 此题的方法除了用线段树求子树,通过标记父亲,更新儿子的方法,来更新祖先,学习了. 对于建树的方法由于并没有说明父亲与儿子的顺序,所以需要通过两次添加. 并且pre变量可以获得父亲的位置,还未弄懂! */ #define _CRT_SECURE_NO_WARNINGS #include<cstring> #include<cstdio> #include<iostream> #include<algorithm> using namespace std;

343D/Codeforces Round #200 (Div. 1) D. Water Tree dfs序+数据结构

D. Water Tree Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a reservoir which can be either empty or filled with water. The vertices of the tree are numbered from 1 to n with the root at vertex 1. For

xtu summer individual 6 F - Water Tree

Water Tree Time Limit: 4000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Original ID: 343D64-bit integer IO format: %I64d      Java class name: (Any) Mad scientist Mike has constructed a rooted tree, which consists of n vertice

Water Tree(树链剖分+dfs时间戳)

Water Tree http://codeforces.com/problemset/problem/343/D time limit per test 4 seconds memory limit per test 256 megabytes input standard input output standard output Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Ea

Problem - D - Codeforces Fix a Tree

Problem - D - Codeforces  Fix a Tree 看完第一名的代码,顿然醒悟... 我可以把所有单独的点全部当成线,那么只有线和环. 如果全是线的话,直接线的条数-1,便是操作数. 如果有环和线,环被打开的同时,接入到线上.那就是线和环的总数-1. 如果只有环的话,把所有的环打开,互相接入,共需n次操作. #include <cstdio> #include <algorithm> using namespace std; const int maxn =