zoukankan      html  css  js  c++  java
  • HDU 3974 Assign the task

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=3974

    解题思路:深搜设置时间戳,然后线段树上更新查询即可。

    第一次写,还算顺利(尽管wa了两发)。

    代码:

      1 const int maxn = 5e4 + 5;
      2 //静态链表前向星保存图
      3 struct Edge{
      4     int to, next;
      5     int val;
      6 };
      7 int head[maxn], tot;
      8 Edge edges[maxn];
      9 //dfs 时间戳 - st 表示开始时间, ed 表示结束时间, cnt 总的节点个数
     10 int st[maxn], ed[maxn], cnt;
     11 int tree[maxn * 4], ass[maxn * 4], vis[maxn];//tree 线段树节点值, ass 区间更新延迟标记, vis 查找根节点用
     12 int n, m;
     13 
     14 void init(){
     15     memset(head, -1, sizeof(head));
     16     memset(tree, -1, sizeof(tree));
     17     memset(ass, -1, sizeof(ass));
     18     memset(vis, 0, sizeof(vis));
     19     tot = 0;
     20     cnt = 0;
     21 }
     22 void addEdge(int u, int v, int w){
     23     edges[tot].to = v;
     24     edges[tot].val = w;
     25     edges[tot].next = head[u];
     26     head[u] = tot++;
     27 }
     28 //深度优先搜索为每个节点设置时间戳
     29 //画个图很容易看到对应区间关系,父节点区间总是包含子节点的区间
     30 //在线段树的节点中,叶子节点对应的标号是每个节点的起始时间st[u]
     31 void dfs(int u){
     32     cnt++;
     33     //起始时间
     34     st[u] = cnt;
     35     for(int i = head[u]; i != -1; i = edges[i].next){
     36         //对子节点深搜
     37         dfs(edges[i].to);
     38     }
     39     //结束时间
     40     ed[u] = cnt;
     41 }
     42 void build(int l, int r, int k){
     43     if(l == r) {
     44         ass[k] = tree[k] = -1;
     45         return;
     46     }
     47     int mid = (l + r) >> 1, lc = k << 1, rc = k << 1;
     48     build(l, mid, lc);
     49     build(mid + 1, r,rc);
     50 }
     51 //延迟标记ass,初始为-1,每次update或者query时要pushdown到子节点
     52 void update(int ul, int ur, int x, int l, int r, int k){
     53     if(ul == l && ur == r){
     54         ass[k] = x;
     55         return;
     56     }
     57     if(ul > r || ur < l) return;
     58     if(l == r){
     59         tree[k] = x;
     60         ass[k] = -1;
     61         return;
     62     }
     63     
     64     int lc = k << 1, rc = k << 1 | 1;
     65     if(ass[k] != -1){
     66         tree[k] = ass[k];
     67         ass[lc] = ass[k];
     68         ass[rc] = ass[k];
     69         ass[k] = -1;
     70     }
     71     
     72     int mid = (l + r) >> 1;
     73     update(ul, ur, x, l, mid, lc);
     74     update(ul, ur, x, mid + 1, r, rc);
     75 }
     76 
     77 int query(int qu, int l, int r, int k){
     78     if(l == qu && r == qu){
     79         if(ass[k] != -1){
     80             tree[k] = ass[k];
     81             return ass[k];
     82         }
     83         return tree[k];
     84     }
     85     int lc = k << 1, rc = k << 1 | 1;
     86     if(ass[k] != -1){
     87         tree[k] = ass[k];
     88         ass[lc] = ass[k];
     89         ass[rc] = ass[k];
     90         ass[k] = -1;
     91     }
     92     
     93     
     94     int mid = (l + r) >> 1;
     95     if(qu <= mid) return query(qu, l, mid, lc);
     96     else return query(qu, mid + 1, r, rc);
     97 }
     98 
     99 int main(){
    100     int T;
    101     scanf("%d", &T);
    102     for(int t = 1; t <= T; t++){
    103         printf("Case #%d:
    ", t);
    104         init();
    105         scanf("%d", &n);
    106         for(int i = 2; i <= n; i++){
    107             int u, v;
    108             scanf("%d %d", &u, &v);
    109             addEdge(v, u, 1);
    110             vis[u]++;
    111         }
    112         for(int i = 1; i <= n; i++){
    113             //从原树根深搜
    114             if(vis[i] == 0){
    115                 dfs(i);
    116                 break;
    117             }
    118         }
    119         build(1, cnt, 1);
    120         scanf("%d", &m);
    121         while(m--){
    122             char ch;
    123             scanf(" %c", &ch);
    124             if(ch == 'C'){
    125                 int x;
    126                 scanf("%d", &x);
    127                 //st[x]为原树x节点对应线段树中的节点编号
    128                 printf("%d
    ", query(st[x], 1, cnt, 1));
    129             }
    130             else{
    131                 int x, y;
    132                 scanf("%d %d", &x, &y);
    133                 //更新时[st[], ed[]]包含了原树上x节点以及其所有子节点
    134                 update(st[x], ed[x], y, 1, cnt, 1);
    135             }
    136         }
    137     }
    138 }

    题目:

    Assign the task

    Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3263    Accepted Submission(s): 1340


    Problem Description
    There is a company that has N employees(numbered from 1 to N),every employee in the company has a immediate boss (except for the leader of whole company).If you are the immediate boss of someone,that person is your subordinate, and all his subordinates are your subordinates as well. If you are nobody's boss, then you have no subordinates,the employee who has no immediate boss is the leader of whole company.So it means the N employees form a tree.

    The company usually assigns some tasks to some employees to finish.When a task is assigned to someone,He/She will assigned it to all his/her subordinates.In other words,the person and all his/her subordinates received a task in the same time. Furthermore,whenever a employee received a task,he/she will stop the current task(if he/she has) and start the new one.

    Write a program that will help in figuring out some employee’s current task after the company assign some tasks to some employee.
     
    
    
    Input
    The first line contains a single positive integer T( T <= 10 ), indicates the number of test cases.

    For each test case:

    The first line contains an integer N (N ≤ 50,000) , which is the number of the employees.

    The following N - 1 lines each contain two integers u and v, which means the employee v is the immediate boss of employee u(1<=u,v<=N).

    The next line contains an integer M (M ≤ 50,000).

    The following M lines each contain a message which is either

    "C x" which means an inquiry for the current task of employee x

    or

    "T x y"which means the company assign task y to employee x.

    (1<=x<=N,0<=y<=10^9)
     
    
    
    Output
    For each test case, print the test case number (beginning with 1) in the first line and then for every inquiry, output the correspond answer per line.
     
    
    
    Sample Input
    1 5 4 3 3 2 1 3 5 2 5 C 3 T 2 1 C 3 T 3 2 C 3
     
    
    
    Sample Output
    Case #1: -1 1 2
     
    
    
    Source
  • 相关阅读:
    HDU1172 猜数字 广搜
    HDU2688 Rotate
    HDU1006 Tick and Tick 几何
    ADO.NET中的五个主要对象
    .NET开发人员值得关注的七个开源项目
    常用正则表达式
    常用的正则表达式集锦〔转〕
    一个较优雅的GridView隐藏列取值解决方案
    DataTable分组求和
    处理[未处理的“System.StackOverflowException”类型的异常出现在 System.Windows.Fo ...
  • 原文地址:https://www.cnblogs.com/bolderic/p/7291989.html
Copyright © 2011-2022 走看看