题目大意是给一个固定结构的树(结点个数为N , N<=5e4),现在M(M<=5e4)组修改或查询,修改为 x , y 将结点x及其所有后代结点染成颜色y,查询为 x 询问 结点x当前的颜色。
其实就是区间染色问题,不过需要预处理DFS两次,第一次DFS预处理每个结点的后代个数,第二次DFS根据每个结点的后代个数为当前结点分配区间。然后按染色问题处理。
1 #include <bits/stdc++.h> 2 #define Lson(x) ((x)<<1) 3 #define Rson(x) ((x)<<1|1) 4 using namespace std; 5 6 typedef pair<int,int> pii; 7 const pii leisure = make_pair(0,-1); 8 const int maxn = 5e4; 9 struct Edge{ 10 int v; 11 int next; 12 }edges[maxn+10]; 13 int tot = 0; 14 int head[maxn + 10]; 15 bool indegree[maxn+10]; 16 int cntsons[maxn + 10]; 17 pii d[(maxn<<2)+10]; 18 pii subordinates[maxn + 10]; 19 20 void addedge(int u,int v){ 21 edges[tot].v = v; 22 edges[tot].next = head[u]; 23 head[u] = tot ++; 24 } 25 26 void preDFS(int cur){ 27 cntsons[cur] = 0; 28 for(int i = head[cur]; i!=-1; i = edges[i].next){ 29 int son = edges[i].v; 30 preDFS(son); 31 cntsons[cur] += 1 + cntsons[son]; 32 } 33 } 34 35 void DFS(int cur,int L,int R){ 36 subordinates[cur] = make_pair(L,R); 37 int LL = L + 1; 38 for(int i=head[cur];i!=-1;i = edges[i].next){ 39 int v = edges[i].v; 40 DFS(v,LL,LL + cntsons[v]); 41 LL = LL + cntsons[v] + 1; 42 } 43 } 44 45 void build(int s,int t,int p){ 46 d[p] = leisure; 47 if(s == t){ 48 return; 49 } 50 int mid = (s+t) >> 1; 51 build(s,mid,Lson(p)); 52 build(mid+1,t,Rson(p)); 53 } 54 55 void update(int L,int R,pii col,int s,int t,int p){ 56 if(L == s && t == R){ 57 d[p] = max(d[p],col); 58 return; 59 } 60 int mid = (s + t) >> 1; 61 if(R <=mid) update(L,R,col,s,mid,Lson(p)); 62 else if( L > mid) update(L,R,col,mid+1,t,Rson(p)); 63 else update(L,mid,col,s,mid,Lson(p)) , update(mid+1,R,col,mid+1,t,Rson(p)); 64 } 65 66 int query(int L,pii ever,int s,int t,int p){ 67 ever = max(ever,d[p]); 68 if(s==t){ 69 return ever.second; 70 } 71 int mid = (s + t) >> 1; 72 if(L <= mid) return query(L,ever,s,mid,Lson(p)); 73 else query(L,ever,mid+1,t,Rson(p)); 74 } 75 76 int main(){ 77 int T; 78 scanf("%d",&T); 79 for(int cntT=1;cntT<=T;cntT++){ 80 printf("Case #%d: ",cntT); 81 int N; 82 scanf("%d",&N); 83 tot = 0; 84 for(int i = 1;i<=N;++i) { 85 head[i] = -1; 86 indegree[i] = 0; 87 } 88 for(int i=0;i<N-1;++i){ 89 int v,u; 90 scanf("%d%d",&v,&u); 91 addedge(u,v); 92 indegree[v] = true; 93 } 94 int root = 1; 95 for(int i=1;i<=N;++i){ 96 if(!indegree[i]){ 97 root = i; 98 preDFS(i); 99 break; 100 } 101 } 102 DFS(root,1,N); 103 build(1,N,1); 104 // for(int i=1;i<=N;++i){ 105 // printf("%d : %d , %d ",i,subordinates[i].first , subordinates[i].second); 106 // } 107 int M; 108 scanf("%d",&M); 109 int choke = 0; 110 for (int i = 0; i < M; ++i) { 111 char op[3]; 112 scanf("%s",op); 113 if(op[0] == 'C'){ 114 int x; 115 scanf("%d",&x); 116 int L = subordinates[x].first ; 117 printf("%d ",query(L,leisure,1,N,1)); 118 }else{ 119 int x,y; 120 scanf("%d%d",&x,&y); 121 int L = subordinates[x].first , R = subordinates[x].second; 122 pii workcol = make_pair(++choke , y); 123 update(L,R,workcol,1,N,1); 124 } 125 } 126 } 127 return 0; 128 }