题目链接:https://vjudge.net/contest/332656#problem/F
题意:
给出一个有向树,初始所有节点为-1.有两种操作,一种为(T,x,y),表示将x节点的所有子树中的节点变为y,另一种为(C,x),为求x节点的值
思路:
采用 dfs序 使得每个结点以及它的孩子都是连续的!
1 #include <math.h> 2 #include <stdio.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <string> 6 #include <string.h> 7 #include <vector> 8 #include <map> 9 #include <stack> 10 #include <set> 11 #include <random> 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<n;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序 + 线段树)
原文:https://www.cnblogs.com/-Ackerman/p/11652250.html