• HDU 3974 Assign the task (DFS序 + 线段树)


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

    给你T组数据,n个节点,n-1对关系,右边的是左边的父节点,所有的值初始化为-1,然后给你q个操作:

    有两种操作:

      操作一:T X Y ,将以X为根的子树上的所有节点都变成Y。

      操作二:C X,查询第X号点是多少?

    没想到是线段树做,就算想到了也想不到用dfs序做...

    例子中给你了这样的树:

         2

            /    

          3       5

        /   

      4      1

    DFS一遍转化成DFS序:2344113552

    然后记录下每个数字最左边和最右边的位置,如:left[3] = 2,  right[3] = 7。

    因为是DFS序,所以他的子节点的范围一定包含在他的左右位置中。

    所以就变成了很明显的线段树成段更新...

    注意一点的是,查询是单点更新...

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 using namespace std;
      5 const int MAXN = 1e5 + 5;
      6 const int INF = 1e9 + 7;
      7 struct segtree {
      8     int l , r , val , lazy;
      9 }T[MAXN << 2];
     10 struct data {
     11     int next , to;
     12 }edge[MAXN];
     13 int head[MAXN] , cont , L[MAXN] , R[MAXN];
     14 //链式前向星
     15 inline void add(int u , int v) {
     16     edge[cont].to = v;
     17     edge[cont].next = head[u];
     18     head[u] = cont++;
     19 }
     20 //DFS序
     21 void dfs(int u) {
     22     L[u] = min(L[u] , ++cont);
     23     R[u] = max(R[u] , cont);
     24     for(int i = head[u] ; ~i ; i = edge[i].next) {
     25         int v = edge[i].to;
     26         dfs(v);
     27     }
     28     L[u] = min(L[u] , ++cont);
     29     R[u] = max(R[u] , cont);
     30 }
     31 
     32 void init(int p , int l , int r) {
     33     int mid = (l + r) >> 1;
     34     T[p].l = l , T[p].r = r , T[p].lazy = 0;
     35     if(l == r) {
     36         T[p].val = -1;
     37         return ;
     38     }
     39     init(p << 1 , l , mid);
     40     init((p << 1)|1 , mid + 1 , r);
     41 }
     42 
     43 void updata(int p , int l , int r , int val) {
     44     int mid = (T[p].l + T[p].r) >> 1;
     45     if(l == T[p].l && T[p].r == r) {
     46         T[p].val = val;
     47         T[p].lazy = val;
     48         return ;
     49     }
     50     if(T[p].lazy) {
     51         T[p << 1].val = T[(p << 1)|1].val = T[p << 1].lazy = T[(p << 1)|1].lazy = T[p].lazy;
     52         T[p].lazy = 0;
     53     }
     54     if(r <= mid) {
     55         updata(p << 1 , l , r , val);
     56     }
     57     else if(l > mid) {
     58         updata((p << 1)|1 , l , r , val);
     59     }
     60     else {
     61         updata(p << 1 , l , mid , val);
     62         updata((p << 1)|1 , mid + 1 , r , val);
     63     }
     64 }
     65 
     66 int query(int p , int index) {
     67     int mid = (T[p].l + T[p].r) >> 1;
     68     if(index == T[p].l && T[p].r == index) {
     69         return T[p].val;
     70     }
     71     if(T[p].lazy) {
     72         T[p << 1].val = T[(p << 1)|1].val = T[p << 1].lazy = T[(p << 1)|1].lazy = T[p].lazy;
     73         T[p].lazy = 0;
     74     }
     75     if(index <= mid) {
     76         return query(p << 1 , index);
     77     }
     78     else {
     79         return query((p << 1)|1 , index);
     80     }
     81 }
     82 
     83 int main()
     84 {
     85     int t , n , u , v , root , q;
     86     char str[5];
     87     scanf("%d" , &t);
     88     for(int ca = 1 ; ca <= t ; ca++) {
     89         scanf("%d" , &n);
     90         cont = 0 , root = (n + 1) * n / 2;
     91         for(int i = 1 ; i <= n ; i++) {
     92             R[i] = head[i] = -1;
     93             L[i] = INF;
     94         }
     95         for(int i = 1 ; i < n ; i++) {
     96             scanf("%d %d" , &u , &v);
     97             root -= u;
     98             add(v , u);
     99         }
    100         cont = 0;
    101         dfs(root);
    102         init(1 , 1 , cont);
    103         printf("Case #%d:
    " , ca);
    104         scanf("%d" , &q);
    105         while(q--) {
    106             scanf("%s" , str);
    107             if(str[0] == 'T') {
    108                 scanf("%d %d" , &u , &v);
    109                 updata(1 , L[u] , R[u] , v);
    110             }
    111             else {
    112                 scanf("%d" , &u);
    113                 printf("%d
    " , query(1 , L[u]));
    114             }
    115         }
    116     }
    117 }
  • 相关阅读:
    安卓开发学习笔记(七):仿写腾讯QQ登录注册界面
    android studio 撤销和恢复
    安卓开发学习笔记(六):如何实现指定图片定时开屏功能?
    JAVA小白开发环境配置(编译器为Idea)
    我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。
    安卓开发学习笔记(五):史上最简单且华丽地实现Android Stutio当中Webview控件https/http协议的方法
    安卓开发学习笔记(四):Android Stuidio无法实现隐式Intent是为什么?
    XML如何添加注释?
    安卓开发学习笔记(三):Android Stuidio无法引用Intent来创建对象,出现cannot resolve xxx
    安卓开发学习笔记(二):如何用Android Stuidio在res资源下创建xml视图文件
  • 原文地址:https://www.cnblogs.com/Recoder/p/5359718.html
Copyright © 2020-2023  润新知