F-Assign the task(dfsシーケンス+セグメントツリー)

17657 ワード

タイトルリンク:https://vjudge.net/contest/332656#problem/F
 
タイトル:
初期のすべてのノードが-1である有向ツリーが与えられる.(T,x,y)という2つの操作があり、xノードのすべてのサブツリーのノードをyにすることを表し、もう1つは(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:
",t++); 113 while (m--) { 114 scanf("%s",op); 115 if (op[0] == 'C') { 116 scanf("%d",&a); 117 printf("%d
",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 }