J - Assign the task HDU - 3974 (线段树 + dfs序)

Posted 千摆渡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了J - Assign the task HDU - 3974 (线段树 + dfs序)相关的知识,希望对你有一定的参考价值。

题意:给一颗树,两种操作,查询 i 结点的颜色,和将i结点和它的子树都染成另一种颜色

题解:dfs序构建线段树,对于x和其子树染色就是 l[x] 和 r[x];

dfs序线段树板子

 

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<list>
#include<math.h>
#include<vector>
#include<stack>
#include<string>
#include<stdio.h>

using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 10;

vector<int>vec[MAXN];
int cnt[MAXN],l[MAXN],r[MAXN],vis[MAXN];
int st[MAXN << 2];
void init() {
    memset(l,-1,sizeof l);
    memset(r, -1 ,sizeof r);
    memset(cnt, 0, sizeof cnt);
    memset(vis, 0, sizeof vis);
}

void dfs(int x,int &pos) {
    l[x] = pos ++;
    for(int i = 0; i < vec[x].size(); i++) {
        dfs(vec[x][i],pos);
    }
    r[x] = pos++;
}
void build(int o,int l,int r) {
    st[o] = -1;
    if(l == r) return;
    int mid = (l + r) >> 1;
    build(o << 1, l , mid);
    build(o << 1 | 1, mid + 1, r);
}
void pushdown(int o) {
    if(st[o] != -1) {
        st[o << 1] = st[o];
        st[o << 1 | 1 ] = st[o];
        st[o] = -1;
    }
}
int query(int o,int l,int r,int x) {
    if(l == r) return st[o];
    pushdown(o);
    int mid = (l + r) >> 1;
    if(x <= mid) query(o << 1, l, mid, x);
    else query(o << 1 | 1, mid + 1, r, x);
}
void update(int o,int l,int r,int ql,int qr,int y) {
    if(ql <= l && r  <= qr) {
        st[o] = y;
        return;
    }
    pushdown(o);
    int mid = (l + r) >> 1;
    if(ql <= mid) update(o << 1, l, mid, ql, qr, y);
    if(qr >= mid + 1) update(o << 1 | 1, mid + 1, r, ql, qr, y);
}
int main() {
    int t, _ = 1;
    scanf("%d", &t);
    while (t--) {
        init();
        printf("Case #%d:\n", _++);
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
            vec[i].clear();
        build(1, 1, 2 * n);
        int u, v;
        for (int i = 1; i < n; i++) {
            scanf("%d %d", &u, &v);
            vec[v].push_back(u);
            cnt[u]++;
        }
        int pos = 1;
        for (int i = 1; i <= n; i++) {
            if (cnt[i] == 0) {
                dfs(i,pos);
                break;
            }
        }
//        for(int i = 1;i<=n;i++)
//            printf("%d %d %d\n",i,l[i],r[i]);

        int m;
        scanf("%d",&m);
        while (m--) {
            char s[5];
            int x,y;
            scanf("%s",s);
            if(s[0] == C) {
                scanf("%d",&x);
                printf("%d\n",query(1,1,2 * n,l[x]));
            } else {
                scanf("%d %d",&x,&y);
                update(1, 1, 2 * n, l[x],r[x], y);
            }
        }
    }
}

/*

1
5
4 3
3 2
1 3
5 2
5
C 3
T 2 1
C 3
T 3 2
C 3


 */

 

以上是关于J - Assign the task HDU - 3974 (线段树 + dfs序)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 3974 Assign the task

HDU 3947 Assign the task

HDU 3974 Assign the task(线段树)

HDU3974 Assign the task

HDU 3974 Assign the task

Assign the task HDU