Water Tree

给出一棵树,有三种操作:

1 x:把以x为子树的节点全部置为1

2 x:把x以及他的所有祖先全部置为0

3 x:询问节点x的值

分析:

  昨晚看完题,马上想到直接树链剖分,在记录时间戳时需要记录一下出去时的时间戳,然后就是很裸很裸的树链剖分了。

  稳稳的黄名节奏,因为一点私事所以没做导致延迟了

  

  (ps:后来想了一下,不用树链剖分直接dfs序维护也行。。。)

#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define debug puts("here")
#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)
#define pb push_back
#define RD(n) scanf("%d",&n)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
#define All(vec) vec.begin(),vec.end()
#define MP make_pair
#define PII pair<int,int>
#define PQ priority_queue
#define cmax(x,y) x = max(x,y)
#define cmin(x,y) x = min(x,y)
#define Clear(x) memset(x,0,sizeof(x))
/*

#pragma comment(linker, "/STACK:1024000000,1024000000")

int size = 256 << 20; // 256MB
char *p = (char*)malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p) );

*/

/******** program ********************/

char op,s[12];
int tp;
inline void Int(int &x){
    while( !isdigit(op=getchar()) );
    x = op-'0';
    while( isdigit(op=getchar()) )
        x = x*10+op-'0';
}
inline void LL(ll &x){
    while( !isdigit(op=getchar()) );
    x = op-'0';
    while( isdigit(op=getchar()) )
        x = x*10+op-'0';
}
inline void Out(ll x){
    s[0] = '0';
    tp = 0;
    while(x){
        s[tp++] = x%10+'0';
        x /= 10;
    }
    for(int i=tp-1;i>=0;i--)
        putchar(s[i]);
    puts("");
}

const int MAXN = 500005;

int son[MAXN],sz[MAXN],dep[MAXN],fa[MAXN],top[MAXN],tim;
bool use[MAXN];
int st[MAXN],ed[MAXN];
int po[MAXN],tol;
int n,m;

struct Edge{
    int y,next;
}edge[MAXN<<1];

inline void add(int x,int y){
    edge[++tol].y = y;
    edge[tol].next = po[x];
    po[x] = tol;
}

// 树链剖分
void dfsFind(int x,int pa,int depth){
    son[x] = 0;
    sz[x] = 1;
    dep[x] = depth;
    fa[x] = pa;
    for(int i=po[x];i;i=edge[i].next){
        int y = edge[i].y;
        if(y==pa)continue;
        dfsFind(y,x,depth+1);
        sz[x] += sz[y];
        if(sz[y]>sz[son[x]])
            son[x] = y;
    }
}

void dfsCon(int x,int pa){
    use[x] = true;
    top[x] = pa;
    st[x] = ++ tim; // 记录进入时的时间戳
    if(son[x])dfsCon(son[x],pa);
    for(int i=po[x];i;i=edge[i].next){
        int y = edge[i].y;
        if(!use[y])dfsCon(y,y);
    }
    ed[x] = tim;
}

// 线段树部分
struct segTree{
    int l,r;
    int col,lz;
    inline int mid(){
        return (l+r)>>1;
    }
}tree[MAXN<<2];

inline void push(int rt){
    if(tree[rt].lz){
        tree[rt<<1].lz = tree[rt<<1|1].lz = 1;
        tree[rt<<1].col = tree[rt<<1|1].col = tree[rt].col;
        tree[rt].lz = 0;
    }
}

void build(int l,int r,int rt){
    tree[rt].l = l;
    tree[rt].r = r;
    tree[rt].lz = 0;
    tree[rt].col = 0;
    tree[rt].lz = 0;
    if(l==r)return;
    int mid = tree[rt].mid();
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
}

void modify(int l,int r,bool col,int rt){
    if(l<=tree[rt].l&&tree[rt].r<=r){
        tree[rt].lz = true;
        tree[rt].col = col;
        return;
    }
    push(rt);
    int mid = tree[rt].mid();
    if(r<=mid)modify(l,r,col,rt<<1);
    else if(l>mid)modify(l,r,col,rt<<1|1);
    else{
        modify(l,r,col,rt<<1);
        modify(l,r,col,rt<<1|1);
    }
}

int ask(int pos,int rt){
    if(tree[rt].l==tree[rt].r)
        return tree[rt].col;
    push(rt);
    int mid = tree[rt].mid();
    if(pos<=mid)return ask(pos,rt<<1);
    else return ask(pos,rt<<1|1);
}

inline void lca(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])
            swap(x,y);
        modify( st[top[x]],st[x],0,1 );
        x = fa[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    modify(st[x],st[y],0,1);
}

int main(){

#ifndef ONLINE_JUDGE
    freopen("sum.in","r",stdin);
    //freopen("sum.out","w",stdout);
#endif

    int n,m,x,y;
    cin>>n;
    REP(i,2,n){
        RD2(x,y);
        add(x,y);
        add(y,x);
    }

    dfsFind(1,1,1);
    Clear(use);
    tim = 0;
    dfsCon(1,1);

    build(1,n,1);

    RD(m);
    while(m--){
        RD2(y,x);
        if(y==1)
            modify( st[x],ed[x],1,1 );
        else if(y==2)
            lca(1,x);
        else
            printf("%d\n",ask(st[x],1));
    }

    return 0;
}

  

Codeforces Round #200 (Div. 1) D Water Tree 树链剖分 or dfs序的更多相关文章

  1. Codeforces Round #200 (Div. 1)D. Water Tree dfs序

    D. Water Tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/343/problem/ ...

  2. Codeforces Round #200 (Div. 1) D. Water Tree(dfs序加线段树)

    思路: dfs序其实是很水的东西.  和树链剖分一样, 都是对树链的hash. 该题做法是:每次对子树全部赋值为1,对一个点赋值为0,查询子树最小值. 该题需要注意的是:当我们对一棵子树全都赋值为1的 ...

  3. Codeforces Round #329 (Div. 2) D. Happy Tree Party 树链剖分

    D. Happy Tree Party Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/593/p ...

  4. Codeforces Round #329 (Div. 2) D. Happy Tree Party LCA/树链剖分

    D. Happy Tree Party     Bogdan has a birthday today and mom gave him a tree consisting of n vertecie ...

  5. CodeForces 916E Jamie and Tree(树链剖分+LCA)

    To your surprise, Jamie is the final boss! Ehehehe. Jamie has given you a tree with n vertices, numb ...

  6. 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 ...

  7. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

  8. 【BZOJ-4353】Play with tree 树链剖分

    4353: Play with tree Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 31  Solved: 19[Submit][Status][ ...

  9. SPOJ Query on a tree 树链剖分 水题

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

随机推荐

  1. XML Schema and XMLspy notes

    Introduction An xml documents consists of elements, attributes and text. There are two structures in ...

  2. android自动获取短信验证码

    前言:android应用的自动化测试必然会涉及到注册登录功能,而许多的注册登录或修改密码功能常常需要输入短信验证码,因此有必要能够自动获得下发的短信验证码.主要就是实时获取短信信息.android上获 ...

  3. stdio.h----标准的输入输出函数

    C++兼容了stdio.h函数,其用法和c一样. 命令形式 #include <stdio.h>; 1.

  4. thinkphp加载 和url_model

    1.加载thinkphp.php requrie('./ThinkPHP/ThinkPHP.php'); 2.加载核心文件 ./thinkPHP/LIB/core 3.加载项目的文件 分析URL 调用 ...

  5. 深入浅出OOP(四): 多态和继承(抽象类)

    在本文中,我们讨论OOP中的热点之一:抽象类.抽象类在各个编程语言中概念是一致的,但是C#稍微有些不一样.本文中我们会通过代码来实现抽象类,并一一进行解析. Abstract Classes 在微软的 ...

  6. linux的5个查找命令_转

    转自:http://www.ruanyifeng.com/blog/2009/10/5_ways_to_search_for_files_using_the_terminal.html 在Linux中 ...

  7. Android开发-API指南-&lt;category&gt;

    <category> 英文原文:http://developer.android.com/guide/topics/manifest/category-element.html 采集(更新 ...

  8. 用于分类的决策树(Decision Tree)-ID3 C4.5

    决策树(Decision Tree)是一种基本的分类与回归方法(ID3.C4.5和基于 Gini 的 CART 可用于分类,CART还可用于回归).决策树在分类过程中,表示的是基于特征对实例进行划分, ...

  9. PP常见数据表

    Table表    Short text短文本 AFFL    Work order sequence加工单顺序 AFFT    Order process instructions订单-流程指令 A ...

  10. 【ASP.NET MVC】&quot;[A]System.Web.WebPages.Razor.Configuration.HostSection 无法强制转换为 ...&quot;的解决办法

    1.错误页面: “/”应用程序中的服务器错误. [A]System.Web.WebPages.Razor.Configuration.HostSection 无法强制转换为 [B]System.Web ...