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 }
原文地址:https://www.cnblogs.com/alihenaixiao/p/5495070.html