F - Assign the task (dfs序 + 线段树)

题目链接:https://vjudge.net/contest/332656#problem/F

 

题意:

给出一个有向树,初始所有节点为-1.有两种操作,一种为(T,x,y),表示将x节点的所有子树中的节点变为y,另一种为(C,x),为求x节点的值

 

思路:

采用 dfs序 使得每个结点以及它的孩子都是连续的! 

 

  1 #include 
  2 #include 
  3 #include 
  4 #include 
  5 #include <string>
  6 #include <string.h>
  7 #include 
  8 #include 
  9 #include 
 10 #include <set>
 11 #include 
 12 
 13 
 14 #define LL long long
 15 
 16 const int maxn = 2e5 + 10;
 17 
 18 struct Edge {
 19     int to,next;
 20 }e[maxn];
 21 
 22 int head[maxn],vis[maxn],tot;
 23 int tree[maxn<<2];
 24 int st[maxn],ed[maxn];
 25 int num;
 26 
 27 void init() {
 28     memset(head,-1, sizeof(head));
 29     memset(vis,0, sizeof(vis));
 30     tot = 0;
 31 }
 32 
 33 void add_edge(int u,int v) {
 34     e[++tot] = Edge{v,head[u]};
 35     head[u] = tot;
 36 }
 37 
 38 void dfs(int u) {
 39     st[u] = ++num; // boss
 40     for (int i=head[u];~i;i=e[i].next) {
 41         dfs(e[i].to);
 42     }
 43     ed[u] = num;
 44 }
 45 
 46 void pushdown(int nod) {
 47     if (tree[nod] != -1) {
 48         tree[nod<<1] = tree[(nod<<1)+1] = tree[nod];
 49         tree[nod] = -1;
 50     }
 51 }
 52 
 53 void build(int l,int r,int nod) {
 54     tree[nod] = -1;
 55     if (l == r)
 56         return ;
 57     int mid = (l + r) >> 1;
 58     build(l,mid,nod<<1);
 59     build(mid+1,r,(nod<<1)+1);
 60 }
 61 
 62 void modify(int L,int R,int c,int l,int r,int nod) {
 63     if (L <= l && R >= r) {
 64         tree[nod] = c;
 65         return ;
 66     }
 67     pushdown(nod);
 68     int mid = (l + r) >> 1;
 69     if (L <= mid) {
 70         modify(L,R,c,l,mid,nod<<1);
 71     }
 72     if (R > mid) {
 73         modify(L,R,c,mid+1,r,(nod<<1)+1);
 74     }
 75 }
 76 
 77 int query(int pos,int l,int r,int nod) {
 78     if (l == r)
 79         return tree[nod];
 80     pushdown(nod);
 81     int mid = (l + r) >> 1;
 82     if (pos <= mid) {
 83         return query(pos,l,mid,nod<<1);
 84     } else {
 85         return query(pos,mid+1,r,(nod<<1)+1);
 86     }
 87 }
 88 
 89 int main() {
 90     int T,n,m;
 91     int t = 1;
 92     char op[10];
 93     scanf("%d",&T);
 94     while (T--) {
 95         scanf("%d",&n);
 96         init();
 97         int a,b;
 98         for (int i=1;i) {
 99             scanf("%d%d",&a,&b);
100             vis[a] = 1;
101             add_edge(b,a);
102         }
103         num = 0;
104         for (int i=1;i<=n;i++) {
105             if (!vis[i]) {
106                 dfs(i);
107                 break;
108             }
109         }
110         build(1,num,1);
111         scanf("%d",&m);
112         printf("Case #%d:\n",t++);
113         while (m--) {
114             scanf("%s",op);
115             if (op[0] == 'C') {
116                 scanf("%d",&a);
117                 printf("%d\n",query(st[a],1,num,1));
118             } else {
119                 scanf("%d%d",&a,&b);
120                 modify(st[a],ed[a],b,1,num,1);
121             }
122         }
123     }
124     return 0;
125 }

 

你可能感兴趣的:(F - Assign the task (dfs序 + 线段树))