[Codeforces343D] Water Tree 树链剖分

来源:互联网 发布:homer软件下载 编辑:程序博客网 时间:2024/06/05 10:09

既然讲了这题,就写一写吧
直接剖,没啥好想的

#include <iostream>#include <cstdio>#include <vector>#define mid ( (l + r) >> 1 )#define ls l,mid,t<<1#define rs mid+1,r,t<<1^1#define N 500050using namespace std;int son[N],siz[N],fa[N],top[N],a[N],L[N],R[N];int cur,ans,n,m,p,ll,rr,v;int ag[4*N];vector<int> e[N];void dfs1(int u,int f) {    siz[u] = 1; fa[u] = f;    for (int i=0;i<(int)e[u].size();i++) {        int v = e[u][i]; if (v == f) continue;        dfs1(v,u); siz[u] += siz[v];        if (!son[u] || siz[v] > siz[ son[u] ]) son[u] = v;    }}void dfs2(int u,int h,int f) {    top[u] = h; a[++cur] = 0; L[u] = cur;    if (son[u]) dfs2(son[u],h,u);    for (int i=0;i<(int)e[u].size();i++) {        int v = e[u][i];         if (v == f || v == son[u]) continue;        dfs2(v,v,u);    }    R[u] = cur;}void push_down(int t) {    if (ag[t] == -1) return ;    ag[t<<1] = ag[t<<1^1] = ag[t]; ag[t] = -1;}void update(int l,int r,int t) {    if (l > rr || r < ll) return ;    if (l >= ll && r <= rr) { ag[t] = v; return ; }    push_down(t); update(ls); update(rs);}void query(int l,int r,int t) {    if (l > p || r < p) return ;    if (l == r) { ans = ag[t]; return ; }    push_down(t); query(ls); query(rs);}int main() {    scanf("%d",&n);    for (int i=1;i<=n-1;i++) {        int x,y; scanf("%d%d",&x,&y);        e[x].push_back(y);        e[y].push_back(x);    }    dfs1(1,0);     dfs2(1,1,1);    scanf("%d",&m);    while (m--) {        int cmd=0 , x=0;        scanf("%d%d",&cmd,&x);        if (cmd == 1) {            ll = L[x] , rr = R[x] , v = 1;            update(1,n,1);        }        if (cmd == 2) {            while (x) {                ll = L[ top[x] ] , rr = L[x] , v = 0;                update(1,n,1);                x = fa[ top[x] ];            }        }        if (cmd == 3) {            p = L[x]; query(1,n,1);            printf("%d\n",ans);        }    }    return 0;}
0 0
原创粉丝点击