hdu3974Assign the task(简单树hash,线段树区间更新,单点查询)

题目大意:给定一个上下级关系树,一开始都是没有做事的,然后给定x,y,就是指定x及其下属此时全部做事件y。最后就是查询x此时在做那件事情。

思路:把子树上的点连续的hash到线段树上去,用线段树更新,hash的时候采用dfs后序遍历。

/*****************************************
Author      :Crazy_AC(JamesQi)
Time        :2016
File Name   :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
using namespace std;
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
#define lson rt << 1
#define rson rt << 1 | 1
#define bug cout << "BUG HERE\n"
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;
const double eps = 1e-8;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int nCase = 0;
const int maxn = 50010;
const int maxm = 50010 << 2;
struct Edge {
    int to, nxt;
    Edge() {}
    Edge(int to,int nxt) : to(to), nxt(nxt) {}
}edges[maxn<<1];
int head[maxn], ecnt;
int lef[maxn], rig[maxn], id[maxn];
int vis[maxn];
int n, cnt;
int dfs(int u,int fa) {
    int first = 1;
    int l;
    for (int i = head[u];~i; i = edges[i].nxt) {
        int v = edges[i].to;
        if (v == fa) continue;
        if (first) l = dfs(v, u);
        else dfs(v, u);
        first = 0;
    }
    id[u] = ++cnt;
    if (first) lef[u] = cnt;//leaf
    else lef[u] = l;//internal
    rig[u] = cnt;
    return lef[u];
}
struct Seg {
    int l, r;
    int flag;
    int val;
}p[maxm];
void build(int rt,int L,int R) {
    p[rt].l = L, p[rt].r = R, p[rt].flag = 0, p[rt].val = -1;
    if (L == R) return ;
    int mid = (L + R) >> 1;
    build(lson, L, mid);
    build(rson, mid + 1, R);
}
void down(int rt) {
    if (p[rt].flag) {
        p[lson].flag = p[rson].flag = p[rt].flag;
        p[lson].val = p[rson].val = p[rt].val;
        p[rt].flag = 0;
    }
}
int Query(int rt,int pos) {
    if (p[rt].l == p[rt].r && p[rt].l == pos) return p[rt].val;
    down(rt);
    int mid = (p[rt].l + p[rt].r) >> 1;
    if (pos <= mid) return Query(lson, pos);
    return Query(rson, pos);
}
void Modify(int rt,int L,int R,int val) {
    if (L <= p[rt].l && p[rt].r <= R) {
        p[rt].flag = val;
        p[rt].val = val;
        return ;
    }
    down(rt);
    int mid = (p[rt].l + p[rt].r) >> 1;
    if (L <= mid) Modify(lson, L, R, val);
    if (R > mid) Modify(rson, L, R, val);
}
int main(int argc, const char * argv[])
{    
    // freopen("in.txt","r",stdin);
    // freopen("out.txt","w",stdout);
    int t;
    cin >> t;
    while(t--) {
        cnt = 0;
        memset(head, -1,sizeof head), ecnt = 0;
        memset(vis, 0,sizeof vis);
        scanf("%d",&n);
        int u, v;
        for (int i = 1;i < n;++i) {
            scanf("%d%d",&u,&v);
            vis[u] = 1;
            edges[ecnt] = Edge(v, head[u]), head[u] = ecnt++;
            edges[ecnt] = Edge(u, head[v]), head[v] = ecnt++;
        }
        for (int i = 1;i <= n;++i) {
            if (!vis[i]) {
                dfs(i, -1);
                break;
            }
        }
        build(1, 1, n);
        printf("Case #%d:\n", ++nCase);
        int q;
        scanf("%d",&q);
        char op[10];
        int x, y;
        while(q--) {
            scanf("%s", op);
            if (op[0] == 'C') {
                scanf("%d", &x);
                printf("%d\n", Query(1, id[x]));
            }else {
                scanf("%d%d",&x,&y);
                Modify(1, lef[x], rig[x], y);
            }
        }
    }
    return 0;
}


你可能感兴趣的:(hdu3974Assign the task(简单树hash,线段树区间更新,单点查询))