Assign the task HDU3974

题目链接

题目大意是给一个固定结构的树(结点个数为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:\n",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\n",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\n",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 }
View Code

猜你喜欢

转载自www.cnblogs.com/Kiritsugu/p/11497165.html
今日推荐