• 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
  • 相关阅读:
    curl上传图片文件
    手工制作简单后台模板
    首页自动生成静态化html
    svn-多个项目版本库和自动同步更新post-commit
    Snoopy+phpquery采集demo
    phpstorm使用手册
    mac系统使用帮助
    upupw一键绿色免安装环境包
    去掉文件夹的.svn文件
    centos安装svn服务器
  • 原文地址:https://www.cnblogs.com/bolderic/p/7291989.html
Copyright © 2020-2023  润新知