zoukankan      html  css  js  c++  java
  • URAL 1890 . Money out of Thin Air (dfs序hash + 线段树)

    题目链接:

      URAL 1890 . Money out of Thin Air

    题目描述:

      给出一个公司里面上司和下级的附属关系,还有每一个人的工资,然后有两种询问:

        1:employee x y z ,如果编号为x的员工如果工资小于y,就给他加薪z。

        2:department x y z ,如果编号为x的员工所管辖的范围内(包括自己),所有员工的工资平均数小于y,给该范围加薪z。

      问q次操作后这个公司内每个员工的工资为多少?

    解题思路:

      根据上司和下级的附属关系,可以先建一个有向图,然后对有向图进行dfs,求出每个点的dfs序列,根据序列建线段树,对于每个操作,先判断操作区间内是否需要加薪,如果需要就进行加薪操作。HINT!!!!:判定和加薪操作一定要分开,要不然会出错,比如说在一段整体不需要加薪的区间内,在线段树上,有可能前半段需要加薪,但是后半部分员工的薪水比较高。

      写代码+debug 花费了两个小时,为什么不够熟练,GG!

      1 #include <cstdio>
      2 #include <queue>
      3 #include <stack>
      4 #include <cmath>
      5 #include <cstring>
      6 #include <iostream>
      7 #include <algorithm>
      8 using namespace std;
      9 
     10 typedef __int64 LL;
     11 #define lson root*2
     12 #define rson root*2+1
     13 const int maxn = 50010;
     14 const LL INF = 1e9+7;
     15 
     16 struct node
     17 {
     18     int to, next;
     19 } edge[maxn*2];
     20 struct Node
     21 {
     22     int l, r;
     23     LL  sum, val;
     24     int len()
     25     {
     26         return (r - l + 1);
     27     }
     28     int mid ()
     29     {
     30         return (l + r) / 2;
     31     }
     32 } tree[maxn*4];
     33 int head[maxn], stime[maxn], etime[maxn];
     34 int tot, Max, df[maxn];
     35 LL ans[maxn], w[maxn];
     36 
     37 void add (int from, int to)
     38 {
     39     edge[tot].to = to;
     40     edge[tot].next = head[from];
     41     head[from] = tot ++;
     42 }
     43 void dfs (int u)
     44 {
     45     stime[u] = ++ Max;
     46     df[Max] = u;
     47 
     48     for (int i=head[u]; i!=-1; i=edge[i].next)
     49     {
     50         int v = edge[i].to;
     51         dfs (v);
     52         etime[v] = Max;
     53     }
     54 }
     55 void build (int root, int l, int r)
     56 {
     57     tree[root].l = l;
     58     tree[root].r = r;
     59     tree[root].val = 0;
     60 
     61     if (l == r)
     62     {
     63         tree[root].sum = w[df[l]];
     64         return ;
     65     }
     66 
     67     build (lson, l, tree[root].mid());
     68     build (rson, tree[root].mid()+1, r);
     69     tree[root].sum = tree[lson].sum + tree[rson].sum;
     70 }
     71 
     72 void pushdown (int root)
     73 {
     74     if (tree[root].val == 0 || tree[root].len() == 1)
     75         return ;
     76     tree[lson].sum += tree[lson].len() * tree[root].val;
     77     tree[rson].sum += tree[rson].len() * tree[root].val;
     78     tree[lson].val += tree[root].val;
     79     tree[rson].val += tree[root].val;
     80     tree[root].val = 0;
     81 }
     82 
     83 LL query (int root, int l, int r)
     84 {
     85     if (tree[root].l == l && tree[root].r == r)
     86         return tree[root].sum;
     87 
     88     pushdown (root);
     89 
     90     if (tree[root].mid() >= r)
     91         return query (lson, l, r);
     92     else if (tree[root].mid() < l)
     93         return query (rson, l, r);
     94     else
     95     {
     96         LL num = 0;
     97         num += query (lson, l, tree[root].mid());
     98         num += query (rson, tree[root].mid()+1, r);
     99         return num;
    100     }
    101 }
    102 void updata (int root, int l, int r, LL x)
    103 {
    104     if (tree[root].l == l && tree[root].r == r)
    105     {
    106         tree[root].sum += tree[root].len() * x;
    107         tree[root].val += x;
    108         return ;
    109     }
    110 
    111     pushdown (root);
    112 
    113     if (tree[root].mid() >= r)
    114         updata (lson, l, r, x);
    115     else if (tree[root].mid() < l)
    116         updata (rson, l, r, x);
    117     else
    118     {
    119         updata (lson, l, tree[root].mid(), x);
    120         updata (rson, tree[root].mid()+1, r, x);
    121     }
    122 
    123     tree[root].sum = tree[lson].sum + tree[rson].sum;
    124 }
    125 void display (int root)
    126 {
    127     if (tree[root].l == tree[root].r)
    128     {
    129         int num = tree[root].l;
    130         ans[df[num]] = tree[root].sum;
    131         return ;
    132     }
    133 
    134     pushdown (root);
    135     display (lson);
    136     display (rson);
    137 }
    138 
    139 int main ()
    140 {
    141     int n, q;
    142 
    143     while (scanf ("%d %d %I64d", &n, &q, &w[0]) != EOF)
    144     {
    145         memset (head, -1, sizeof(head));
    146         memset (df, 0, sizeof(df));
    147         memset (etime, 0, sizeof(etime));
    148         tot = Max = 0;
    149 
    150         for (int i=1; i<n; i++)
    151         {
    152             int u;
    153             scanf ("%d %I64d", &u, &w[i]);
    154             add (u, i);
    155         }
    156 
    157         dfs (0);
    158         etime[0] = Max;
    159         build (1, 1, n);
    160 
    161         char str[20];
    162         LL x, y, z;
    163 
    164         while (q --)
    165         {
    166             scanf ("%s %I64d %I64d %I64d", str, &x, &y, &z);
    167             if (strcmp (str, "employee") == 0)
    168                 {
    169                     LL tmp = query (1, stime[x], stime[x]);
    170                     if (tmp < y)
    171                         updata(1, stime[x], stime[x], z);
    172                 }
    173             else
    174                 {
    175                     LL tmp = query (1, stime[x], etime[x]);
    176                     LL num = (etime[x] - stime[x] + 1) * y;
    177                     if (tmp < num)
    178                         updata(1, stime[x], etime[x], z);
    179                 }
    180         }
    181 
    182         display (1);
    183 
    184         for (int i=0; i<n; i++)
    185             printf ("%I64d
    ", ans[i]);
    186     }
    187     return 0;
    188 }
  • 相关阅读:
    设置root密码
    切分和组合图片(一)
    android 游戏开发libgdx(一)
    用SharePoint.OpenDocuments打开的文档如何控制它的ActiveWindow.View.ShowXMLMarkup(转)
    sp_helptext 命令
    CMMI 配置管理 简介(转)
    文本框中只能输入字符的正则表达式.
    基于CMM和CMMI的配置管理(转)
    正则表达式详述(转)
    选中多个CheckBox赋给文本框.
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/5495070.html
Copyright © 2011-2022 走看看