ural 1890
来源:互联网 发布:java web获取当前路径 编辑:程序博客网 时间:2024/05/21 06:51
每次更新树上单点或者整个子树,最后查询
把对树的操作改为对区间的操作,更新查询采用线段树去做就可以。
#include <cstdio>#include <cstring>#include <vector>#include <iostream>using namespace std;const int maxn = 100007;struct Seg { int left, right; long long sum, lazy;};struct Seg seg[maxn * 4];int dfs_block;long long salary[maxn], val[maxn];int low[maxn], high[maxn], vis[maxn], n, m;vector<int> path[maxn];void pushUp(int order) { seg[order].sum = seg[order * 2].sum + seg[order * 2 + 1].sum; return ;}void pushDown(int order) { if (seg[order].lazy) { seg[order * 2].sum += (seg[order * 2].right - seg[order * 2].left + 1) * seg[order].lazy; seg[order * 2 + 1].sum += (seg[order * 2 + 1].right - seg[order * 2 + 1].left + 1) * seg[order].lazy; seg[order * 2].lazy += seg[order].lazy; seg[order * 2 + 1].lazy += seg[order].lazy; seg[order].lazy = 0; }}void build(int order, int left, int right) { int mid = (left + right) >> 1; seg[order].left = left; seg[order].right = right; seg[order].lazy = 0; if (left == right) { seg[order].sum = val[left]; return ; } build(order * 2, left, mid); build(order * 2 + 1, mid + 1, right); pushUp(order);}long long query(int order, int left, int right) { int mid = (seg[order].left + seg[order].right) >> 1; if (left <= seg[order].left && right >= seg[order].right) { return seg[order].sum; } pushDown(order); if (right <= mid) { return query(order * 2, left, right); } else if (left > mid) { return query(order * 2 + 1, left, right); } else { return query(order * 2, left, mid) + query(order * 2 + 1, mid + 1, right); }}void update(int order, int left, int right, long long cnt_val) { int mid = (seg[order].left + seg[order].right) >> 1; if (left <= seg[order].left && right >= seg[order].right) { seg[order].lazy += cnt_val; seg[order].sum += (seg[order].right - seg[order].left + 1) * cnt_val; return ; } pushDown(order); if (right <= mid) { update(order * 2, left, right, cnt_val); } else if (left > mid) { update(order * 2 + 1, left, right, cnt_val); } else { update(order * 2, left, mid, cnt_val); update(order * 2 + 1, mid + 1, right, cnt_val); } pushUp(order);}void dfs(int cnt) { low[cnt] = ++dfs_block; for (int i = 0; i < path[cnt].size(); i++) { int v = path[cnt][i]; if (!vis[v]) { vis[v] = 1; dfs(v); } } high[cnt] = dfs_block;}int main() {// freopen("in.txt", "r", stdin); dfs_block = 0; int cnt_s; scanf("%d%d%d", &n, &m, &cnt_s); salary[0] = cnt_s; for (int i = 1; i < n; i++) { int a, b; scanf("%d%d", &a, &b); path[a].push_back(i); path[i].push_back(a); salary[i] = b; } vis[0] = 1; dfs(0); for (int i = 0; i < n; i++) { val[low[i]] = salary[i]; }// for (int i = 0; i < n; i++) {// printf("%d ", low[i]);// }// printf("\n"); build(1, 1, dfs_block); for (int i = 1; i <= m; i++) { char temp[20]; long long a, b, c; cin >> temp >> a >> b >> c; if (temp[0] == 'e') { long long cnt_s = query(1, low[a], low[a]); if (cnt_s < b) { update(1, low[a], low[a], c); } } else { long long cnt_s = query(1, low[a], high[a]); double ave = cnt_s * 1.0 / (high[a] - low[a] + 1); if (ave < b) { update(1, low[a], high[a], c); } } } for (int i = 1; i <= dfs_block; i++) { val[i] = query(1, i, i); } for (int i = 0; i < n; i++) { cout << val[low[i]] << endl; } return 0;}
0 0
- ural 1890
- URAL
- 【ural】
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- Chapter 1 Securing Your Server and Network(13):配置端点安全性
- JavaScript的特点
- SVN用法(merge,branch,switch)
- JavaScript的教程
- JavaScript的徐伦敦网页设计
- ural 1890
- JavaScript的 - 大多数Twitter的追随者屋1.1 - 引言
- iPhone应用程序开发和意义在应用开发领域
- Ubuntu 14.04安装LAMP
- JavaFX的最佳平台,丰富的互联网应用
- jquery面包导航
- storyboard presentViewController pushViewController 跳转后黑屏 NavigationBar按钮push
- JavaScript标记收集数据
- igenuz实时软件高知