CF343D Water Tree 树链剖分

问题描述

LG-CF343D


题解

树剖,线段树维护0-1序列

yzhang:用珂朵莉树维护多好


\(\mathrm{Code}\)

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

template <typename Tp>
void read(Tp &x){
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-'){fh=-1;ch=getchar(); }
    else fh=1;
    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    x*=fh;
}

const int maxn=500007;
const int maxm=1000007;

int n,T;
int Head[maxn],to[maxm],Next[maxm],tot;

void add(int x,int y){
    to[++tot]=y,Next[tot]=Head[x],Head[x]=tot;
}

int size[maxn],son[maxn];
int fa[maxn],dep[maxn],top[maxn],New[maxn],pre[maxn],ind;

void dfs1(int x,int f,int dp){
    size[x]=1,fa[x]=f,dep[x]=dp;
    int mx=-1;
    for(int i=Head[x];i;i=Next[i]){
        int y=to[i];
        if(y==f) continue;
        dfs1(y,x,dp+1);size[x]+=size[y];
        if(size[y]>mx) mx=size[y],son[x]=y;
    }
}

int dfn[maxn];

void dfs2(int x,int tp){
    top[x]=tp,New[x]=++ind,pre[ind]=x,dfn[x]=ind;
    if(!son[x]) return;
    dfs2(son[x],tp);
    for(int i=Head[x];i;i=Next[i]){
        int y=to[i];
        if(y==fa[x]||y==son[x]) continue;
        dfs2(y,y);
    }
    dfn[x]=ind;
}

#define lfc (x<<1)
#define rgc ((x<<1)|1)
#define mid ((l+r)>>1)

int val[maxn<<2],lazy[maxn<<2];

int L,R,need;

void pushdown(int x){
    lazy[lfc]=lazy[rgc]=lazy[x];val[lfc]=val[rgc]=lazy[x]-1;
    lazy[x]=0;
}

void pushup(int x){
    val[x]=val[lfc]+val[rgc];
}

void change(int x,int l,int r){
    if(L>r||R<l) return;
    if(L<=l&&r<=R){
        lazy[x]=need+1,val[x]=need;return;
    }
    if(lazy[x]) pushdown(x);
    change(lfc,l,mid);change(rgc,mid+1,r);
    pushup(x);
}

int query(int x,int l,int r){
    if(l==r) return val[x];
    if(lazy[x]) pushdown(x);
    int res;
    if(L<=mid) res=query(lfc,l,mid);
    else res=query(rgc,mid+1,r);
    pushup(x);
    return res;
}

void cz1(){
    int x;read(x);
    L=New[x],R=dfn[x],need=1;
    change(1,1,n);
}

void cz2(){
    int x,y=1;read(x);
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        L=New[top[x]],R=New[x],need=0;
        change(1,1,n);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    L=New[x],R=New[y],need=0;
    change(1,1,n);
}

void cz3(){
    int x;read(x);
    L=New[x];
    printf("%d\n",query(1,1,n));
}

int main(){
    read(n);
    for(int i=1,x,y;i<n;i++){
        read(x);read(y);
        add(x,y);add(y,x);
    }
    dfs1(1,0,1);dfs2(1,1);
    read(T);int op;
    while(T--){
        read(op);
        if(op==1) cz1();
        else if(op==2) cz2();
        else cz3();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/liubainian/p/11789221.html

时间: 2024-11-02 01:19:43

CF343D Water Tree 树链剖分的相关文章

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

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

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]

SPOJ375 Query on a tree 树链剖分

SPOJ375  Query on a tree   树链剖分 no tags You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. We will ask you to perfrom some instructions of the following form: CHANGE i ti : change the cost of

SPOJ - QTREE 375 Query on a tree 树链剖分+线段树

操作1:修改第k条边权. 操作2:询问两点间最大边权. 树链剖分,然后线段树维护最大值 #include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<set> #include<map> #include<queue> #include<vector> #inclu

Aizu 2450 Do use segment tree 树链剖分+线段树

Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show.php?pid=39566 Description Given a tree with n (1 ≤ n ≤ 200,000) nodes and a list of q (1 ≤ q ≤ 100,000) queries, process the queries in order and out

spoj 375 Query on a tree (树链剖分)

Query on a tree You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. We will ask you to perfrom some instructions of the following form: CHANGE i ti : change the cost of the i-th edge to ti or Q

SPOJ Query on a tree 树链剖分 水题

You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. We will ask you to perfrom some instructions of the following form: CHANGE i ti : change the cost of the i-th edge to tior QUERY a b : ask fo

hdu 4912 Paths on the tree(树链剖分+贪心)

题目链接:hdu 4912 Paths on the tree 题目大意:给定一棵树,和若干个通道,要求尽量选出多的通道,并且两两通道不想交. 解题思路:用树链剖分求LCA,然后根据通道两端节点的LCA深度排序,从深度最大优先选,判断两个节点均没被标 记即为可选通道.每次选完通道,将该通道LCA以下点全部标记. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include