51Nod-1199-Money out of Thin Air
来源:互联网 发布:php 跨平台 编辑:程序博客网 时间:2024/05/21 08:51
ACM模版
描述
题解
树链剖分 + 线段树搞搞,十分不错的一道题,折腾了好久才搞定……其实也不难,树链剖分算是一个比较简单的算法了,最起码好理解,两个 dfs 搞搞事情,获得一个树与链的映射关系即可,然后用这个链来进行线段树的相关处理。
代码
#include <cstdio>#include <cstring>#include <cctype>#include <algorithm>#define lson l, mid, x << 1#define rson mid + 1, r, x << 1 | 1#define ll long longusing namespace std;const int MAXN = 5e4 + 10;struct edge{ int to; int nt; edge() { nt = -1; }};int tot = 0;int head[MAXN];edge eg[MAXN << 1];int read(){ int x = 0; char c = getchar(); while (!isdigit(c)) { c = getchar(); } while (isdigit(c)) { x = x * 10 + c - '0', c = getchar(); } return x;}void add(int p, int pos){ eg[tot].to = pos; eg[tot].nt = head[p]; head[p] = tot++; eg[tot].to = p; eg[tot].nt = head[pos]; head[pos] = tot++;}int N, M;int size[MAXN];int son[MAXN];int idx[MAXN]; // idx[v] 表示 v 和其父节点的连边在线段树中的对应关系int id[MAXN]; // id[v] 表示 v 在原树中的对应关系int w[MAXN];struct node{ ll sum; ll add;};node tree[MAXN << 2];// 查找重边void dfsI(int x = 1, int pre = 0){ size[x] = 1; for (int nt = head[x]; nt != -1; nt = eg[nt].nt) { if (eg[nt].to != pre) { dfsI(eg[nt].to, x); size[x] += size[eg[nt].to]; if (!son[x] || size[eg[nt].to] > size[son[x]]) { son[x] = eg[nt].to; } } }}// 构造重链void dfsII(int x = 1){ id[++id[0]] = x; idx[x] = id[0]; if (son[x]) { dfsII(son[x]); } for (int nt = head[x]; nt != -1; nt = eg[nt].nt) { if (!idx[eg[nt].to]) { dfsII(eg[nt].to); } }}void build(int l = 1, int r = N, int x = 1){ tree[x].add = -1; if (l == r) { tree[x].sum = w[id[l]]; return ; } int mid = (l + r) >> 1; build(lson); build(rson); tree[x].sum = tree[x << 1].sum + tree[x << 1 | 1].sum;}void pushdown(int x, int cnt){ if (tree[x].add != -1) { if (tree[x << 1].add != -1) { tree[x << 1].add += tree[x].add; } else { tree[x << 1].add = tree[x].add; } if (tree[x << 1 | 1].add != -1) { tree[x << 1 | 1].add += tree[x].add; } else { tree[x << 1 | 1].add = tree[x].add; } tree[x << 1].sum += tree[x].add * (cnt - (cnt >> 1)); tree[x << 1 | 1].sum += tree[x].add * (cnt >> 1); tree[x].add = -1; }}// 更新单结点void update1(int p, int add, int l, int r, int x){ if (l == r) { tree[x].sum += add; return ; } pushdown(x, r - l + 1); int mid = (l + r) >> 1; p <= mid ? update1(p, add, lson) : update1(p, add, rson); tree[x].sum = tree[x << 1].sum + tree[x << 1 | 1].sum;}void update2(int tl, int tr, int add, int l, int r, int x){ if (tl <= l && tr >= r) { if (tree[x].add != -1) { tree[x].add += add; } else { tree[x].add = add; } tree[x].sum += (ll)add * (r - l + 1); return ; } pushdown(x, r - l + 1); int mid = (l + r) >> 1; if (tl <= mid) { update2(tl, tr, add, lson); } if (tr > mid) { update2(tl, tr, add, rson); } tree[x].sum = tree[x << 1].sum + tree[x << 1 | 1].sum;}ll query1(int p, int l, int r, int x){ if (l == r) { return tree[x].sum; } pushdown(x, r - l + 1); int mid = (l + r) >> 1; return p <= mid ? query1(p, lson) : query1(p, rson);}ll query2(int tl, int tr, int l, int r, int x){ if (tl <= l && tr >= r) { return tree[x].sum; } pushdown(x, r - l + 1); int mid = (l + r) >> 1; ll ans = 0; if (tl <= mid) { ans += query2(tl, tr, lson); } if (tr > mid) { ans += query2(tl, tr, rson); } return ans;}int main(){// freopen("/Users/zyj/Desktop/input.txt", "r", stdin); memset(head, -1, sizeof(head)); N = read(); M = read(); int p; for (int i = 2; i <= N; i++) { p = read() + 1; w[i] = read(); add(p, i); } dfsI(); dfsII(); build(); int x, y, z; char s[3]; for (int i = 1; i <= M; i++) { scanf("%s", s); x = read() + 1; y = read(); z = read(); if (s[0] == 'S') { if (query1(idx[x], 1, N, 1) < y) { update1(idx[x], z, 1, N, 1); } } else { ll sum = query2(idx[x], idx[x] + size[x] - 1, 1, N, 1); if (sum >= (ll)y * size[x]) { continue; } update2(idx[x], idx[x] + size[x] - 1, z, 1, N, 1); } } for (int i = 1; i <= N; i++) { printf("%lld\n", query1(idx[i], 1, N, 1)); } return 0;}
参考
《树链剖分》
0 0
- 51nod 1199 Money out of Thin Air
- 51Nod-1199-Money out of Thin Air
- 51nod 1199 Money out of Thin Air[线段树]
- 【51nod】1199 Money out of Thin Air 线段树
- 51Nod 1199 Money out of Thin Air(dfs序+线段树维护区间和)
- out of thin air 凭空;无中生有
- Money is not out of the province
- air max pas cher enfant Asian plate Chupan hemisphere generally out of high water dish
- vanished into thin air, I was to see her
- The problem of Money Changes
- thin
- [51nod 1309]Value of all Permutations
- Money
- Money
- money
- money
- Money
- money
- 【编程】【leetcode】523. Continuous Subarray Sum
- Session案例 用户登录
- CTF之登录一下好吗?
- GIT简单入门——初级使用
- CSU
- 51Nod-1199-Money out of Thin Air
- contourArea函数
- linux库文件学习1
- spring 配置内存溢出监听器、文件上传、ie下载json问题
- JUnit 5的前世今生
- 文章标题
- 大二了,第一次写博客!先不写代码,先立flag!
- genl-netlink 协议 Linux kernel 实现 欣赏
- iOS