CF343D Water Tree

Posted ForeverOIer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF343D Water Tree相关的知识,希望对你有一定的参考价值。

\\(Solution:\\)
树链剖分模板题,分两种问题维护

  1. 区间覆盖+单点查询
  2. 路径覆盖

\\(Code:\\)

#include<bits/stdc++.h>
#define int long long
#define lson p<<1
#define rson (p<<1)|1
using namespace std;
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c<\'0\' || c>\'9\'){if(c==\'-\') f=0;c=getchar();}
    while(c>=\'0\' && c<=\'9\') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return f?x:-x;
}
const int N=5e5+5,M=N<<1;
struct SGT{int l,r,sum,add;}t[N<<2];
int tot,ver[M],nxt[M],head[N];
void add(int u,int v)
{
    ver[++tot]=v;
    nxt[tot]=head[u];
    head[u]=tot;
}
int n,m;
void push_up(int p){t[p].sum=t[lson].sum+t[rson].sum;}
void build(int p,int l,int r)
{
    t[p].l=l; t[p].r=r;
    t[p].add=-1;
    if(l==r) return;
    int mid=(l+r)>>1;
    build(lson,l,mid);
    build(rson,mid+1,r);
}
void push_down(int p)
{
    if(~t[p].add)
    {
        t[lson].add=t[p].add; t[rson].add=t[p].add;
        t[lson].sum=t[p].add*(t[lson].r-t[lson].l+1);
        t[rson].sum=t[p].add*(t[rson].r-t[rson].l+1);
        t[p].add=-1;
    }
}
void modify(int p,int l,int r,int d)
{
    if(l<=t[p].l && t[p].r<=r)
    {
        t[p].sum=(t[p].r-t[p].l+1)*d;
        t[p].add=d;
        return;
    }
    push_down(p);
    int mid=(t[p].l+t[p].r)/2;
    if(l<=mid) modify(lson,l,r,d);
    if(r>mid) modify(rson,l,r,d);
    push_up(p);
}
int query(int p,int l,int r)
{
    if(l<=t[p].l && t[p].r<=r) return t[p].sum;
    push_down(p);
    int res=0,mid=(t[p].l+t[p].r)/2;
    if(l<=mid) res+=query(lson,l,r);
    if(r>mid) res+=query(rson,l,r);
    return res;
}
int fa[N],dep[N],son[N],siz[N],top[N],id[N],cnt;
void dfs1(int x)
{
    siz[x]=1; dep[x]=dep[fa[x]]+1;
    for(int i=head[x];i;i=nxt[i])
    {
        int v=ver[i];
        if(v==fa[x]) continue;
        fa[v]=x;
        dfs1(v);
        siz[x]+=siz[v];
        if(siz[v]>siz[son[x]]) son[x]=v;
    }
}
void dfs2(int x,int t)
{
    top[x]=t; id[x]=++cnt;
    if(son[x]) dfs2(son[x],t);
    for(int i=head[x];i;i=nxt[i])
    {
        int v=ver[i];
        if(v==fa[x] || v==son[x]) continue;
        dfs2(v,v);
    }
}
void update(int u,int v,int d)
{
    int fu=top[u],fv=top[v];
    while(fu!=fv)
    {
        if(dep[fu]>=dep[fv])
        {
            modify(1,id[fu],id[u],d);
            u=fa[fu]; fu=top[u];
        }
        else
        {
            modify(1,id[fv],id[v],d);
            v=fa[fv]; fv=top[v];
        }
    }
    if(id[u]<=id[v]) modify(1,id[u],id[v],d);
    else modify(1,id[v],id[u],d);
}
signed main()
{
    n=read();
    build(1,1,n);
    for(int i=1;i<n;i++)
    {
        int u=read(),v=read();
        add(u,v); add(v,u);
    }
    dfs1(1); dfs2(1,1);
    m=read();
    for(int i=1;i<=m;i++)
    {
        int op=read();
        if(op==1)
        {
            int x=read();
            modify(1,id[x],id[x]+siz[x]-1,1);
        }
        else if(op==2)
        {
            int x=read();
            update(1,x,0);
        }
        else
        {
            int x=read();
            printf("%lld\\n",query(1,id[x],id[x]));
        }
    }
    return 0;
}

以上是关于CF343D Water Tree的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 343D Water Tree

CodeForces 343D water tree(树链剖分)

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

CoderForces343D:Water Tree(dfs序+线段树&&特殊处理)

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

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