Loading

HDU3974 Assign the task

描述

传送门:我是传送门

有一家公司有NN个员工(1N)(从1到N),公司里每个员工都有一个直接的老板(除了整个公司的领导)。如果你是某人的直接老板,那个人就是你的下属,他的所有下属也都是你的下属。如果你是没有人的老板,那么你就没有下属,没有直接老板的员工就是整个公司的领导,也就是说NN个员工构成了一棵树。公司通常把一些任务分配给一些员工来完成,当一项任务分配给某个人时,他/她会把它分配给他/她的所有下属,换句话说,这个人和他/她的所有下属在同一时间接受了一项任务。此外,每当员工收到一个任务,他/她将停止当前任务(如果他/她有),并开始新的任务。在公司将某些任务分配给某个员工后,编写一个程序来帮助找出某个员工当前的任务。

(直接贴中文题面,下边就不写题意了)

输入

第一行包含单个正整数T(T<=10)T(T<=10),表示测试用例的数量。对于每个测试用例:第一行包含一个整数N(N50000)N(N≤50,000),它是雇员的数目。下面的N1N−1行分别包含两个整数uu和vv,这意味着雇员v是雇员u的直接老板1<=uv<=N)1<=u,v<=N)。下一行包含一个整数(M50000)(M≤50,000)。下面的M行分别包含一条消息,“CxCx”表示对员工x的当前任务的查询,“TxyTxy”表示公司将任务yy分配给员工xx。(1<=x<=N0<=y<=109)(1<=x<=N,0<=y<=109)

输出

对于每个测试用例,在第一行打印测试用例编号(以1开头),然后为每个查询输出相应的答案。

样例

输入

1
5
4 3
3 2
1 3
5 2
5
C 3
T 2 1
C 3
T 3 2
C 3

输出

Case #1:
-1
1
2

思路

学习了别人的代码才会写,CF马上开始了 下次补上代码中的注释以及自己对这道题的理解

代码

  1 /*
  2  * ===========================================================
  3  *
  4  *       Filename:  J.cpp
  5  *
  6  *           Link:  http://acm.hdu.edu.cn/showproblem.php?pid=3974
  7  *
  8  *        Version:  1.0
  9  *        Created:  2018/09/15 17时29分26秒
 10  *       Revision:  none
 11  *       Compiler:  g++
 12  *
 13  *         Author:  杜宁元 (https://duny31030.top/), duny31030@126.com
 14  *   Organization:  QLU_浪在ACM
 15  *
 16  * ===========================================================
 17  */
 18 #include <bits/stdc++.h>
 19 using namespace std;
 20 #define clr(a, x) memset(a, x, sizeof(a))
 21 #define rep(i,a,n) for(int i=a;i<=n;i++)
 22 #define pre(i,a,n) for(int i=n;i>=a;i--)
 23 #define ll long long
 24 #define max3(a,b,c) fmax(a,fmax(b,c))
 25 #define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 26 const double eps = 1e-6;
 27 const int INF = 0x3f3f3f3f;
 28 const int mod = 1e9 + 7;
 29 const int MAXN = 5e4+100;
 30 int T,N,M,u,v,x,y;
 31 char op[10];
 32 
 33 vector<vector<int> > G;
 34 int s[MAXN],e[MAXN],du[MAXN],Index;
 35 
 36 void dfs(int u)
 37 {
 38     s[u] = ++Index;  // 相当于是记录u的起始下属下标,结束下标在递归回来的时候确定的
 39     int len = G[u].size();
 40     for(int i = 0;i < len;i++)
 41         dfs(G[u][i]);
 42     e[u] = Index;
 43 }
 44 
 45 struct node
 46 {
 47     int l,r;
 48     int task,flag;   // flag表示区间是否被全部覆盖,task表示此区间的工作室什么
 49 }tree[MAXN<<2];
 50 
 51 void Build(int rt,int L,int R)
 52 {
 53     tree[rt].l = L; tree[rt].r = R; tree[rt].task = -1;
 54     if(L == R)
 55         return ;
 56     int mid = (L+R)>>1;
 57     Build(rt<<1,L,mid);
 58     Build(rt<<1|1,mid+1,R);
 59 }
 60 
 61 void Down(int rt)
 62 {
 63     if(tree[rt].flag && tree[rt].l != tree[rt].r)
 64     {
 65         tree[rt<<1].flag = tree[rt<<1|1].flag = tree[rt].flag;
 66         tree[rt<<1].task = tree[rt<<1|1].task = tree[rt].task;
 67         tree[rt].flag = 0;
 68     }
 69 }
 70 
 71 void Update(int rt,int L,int R,int task)
 72 {
 73     if(tree[rt].l == L && tree[rt].r == R)
 74     {
 75         tree[rt].flag = 1;
 76         tree[rt].task = task;
 77         return ;
 78     }
 79     Down(rt);
 80     int mid = (tree[rt].l+tree[rt].r)>>1;
 81     if(R <= mid)
 82         Update(rt<<1,L,R,task);
 83     else 
 84         if(L > mid)
 85             Update(rt<<1|1,L,R,task);
 86         else 
 87         {
 88             Update(rt<<1,L,mid,task);
 89             Update(rt<<1|1,mid+1,R,task);
 90         }
 91 }
 92 
 93 int Query(int rt,int pos)
 94 {
 95     Down(rt);   // 因为上面可能没有更新到最底部
 96     if(tree[rt].l == tree[rt].r)   // 找到叶子节点,并返回
 97         return tree[rt].task;
 98 
 99     int mid = (tree[rt].l+tree[rt].r)>>1;
100     if(pos <= mid)
101         return Query(rt<<1,pos);
102     else 
103         return Query(rt<<1|1,pos);
104 }
105 
106 int main()
107 {
108     ios
109 #ifdef ONLINE_JUDGE 
110 #else 
111         freopen("in.txt","r",stdin);
112     // freopen("out.txt","w",stdout); 
113 #endif
114     scanf("%d",&T);
115     rep(cas,1,T)
116     {
117         printf("Case #%d:\n",cas);
118         clr(du,0);  clr(s,0);   clr(e,0);
119         scanf("%d",&N);
120         G.clear();
121         G.resize(N+5);
122         rep(i,2,N)
123         {   
124             scanf("%d %d",&u,&v);
125             G[v].push_back(u);
126             du[u] = 1;
127         }
128         Index = 0;
129         rep(i,1,N)
130         {
131             if(!du[i])   // 找到根节点,然后按照递归的形式找到自己连续的下属
132             {
133                 dfs(i);
134                 break;
135             }
136         }
137         // 建树
138         Build(1,1,N);
139         scanf("%d",&M);
140         rep(i,1,M)
141         {
142             scanf("%s",op);
143             if(op[0] == 'C')
144             {
145                 scanf("%d",&x);
146                 printf("%d\n",Query(1,s[x]));
147             }
148             else 
149             {
150                 scanf("%d %d",&x,&y);
151                 Update(1,s[x],e[x],y);   // 更新的是x这个人的所有下属
152             }
153         }
154     }
155     fclose(stdin);
156     // fclose(stdout);
157     return 0;
158 }

 

posted @ 2021-01-20 21:01  Yiduuannng  阅读(48)  评论(0编辑  收藏  举报