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\n", ans[i]); 186 } 187 return 0; 188 }
本文为博主原创文章,未经博主允许不得转载。