Codeforces 739B Alyona and a tree (树上差分+二分)
来源:互联网 发布:网络投票刷票器 编辑:程序博客网 时间:2024/06/01 22:44
现在给出“控制”的定义:对一个点u,设点v在其子树上,且
要求求出每个点控制了多少个点
模拟dfs过程,我们很容易发现dfs到点u时,其祖先节点到根的dis值都已经算出,且是单调递增,所以我们可以用二分或者倍增,在log的时间复杂度内找到深度最小的满足
一般写法。。。用id模拟每条路的节点编号,也用于二分
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int maxn = 2e5 + 5;typedef long long ll;ll ans[maxn], path[maxn], a[maxn], pre[maxn], cnt[maxn];struct node{ int to, len; node(){} node(int tt, int ll) : to(tt), len(ll){}};vector<node> p[maxn];void dfs(int x, int id, int f, ll s){ pre[id] = s; path[id] = x;// cout << 1 << endl; if(id > 1) { int l = 1, r = id, temp; while(l <= r) { int mid = (l+r)/2; if(a[x] >= s - pre[mid]) temp = mid, r = mid - 1; else l = mid + 1; } cnt[path[temp-1]]--; cnt[path[id-1]]++; } for(int i = 0; i < p[x].size(); i++) { int to = p[x][i].to; int len = p[x][i].len; dfs(to, id+1, x,len+s); }}void dfs_ans(int x){// cout << 1 << endl; ans[x] = cnt[x]; for(int i = 0; i < p[x].size(); i++) { int to = p[x][i].to; dfs_ans(to); ans[x] += ans[to]; }}int main(){ int n; while(~scanf("%d", &n)) { for(int i = 1; i <= n; i++) scanf("%lld", &a[i]); int x, y; for(int i = 1; i < n; i++) { scanf("%d%d", &x, &y); p[x].push_back(node(i+1, y)); } dfs(1, 1, 1, 0); dfs_ans(1); for(int i = 1; i <= n; i++) { printf("%lld%c", ans[i], i == n ? '\n' : ' '); } }return 0;}
orz网上大神写法,low_bountd劲啊
用队列模拟一条路上的节点
#include<bits/stdc++.h>//#define make_pair MPusing namespace std;typedef __int64 ll;typedef pair<ll, int> PII;const int MAXN = 2e5+5;vector<PII> G[MAXN], path;ll dep[MAXN];int sum[MAXN], a[MAXN];void dfs(int u) { path.push_back(make_pair(dep[u], u)); int it = lower_bound(path.begin(), path.end(), make_pair(dep[u]-a[u],-1))-path.begin()-1; //对vec用二分函数 if(it >= 0) sum[path[it].second]--; for(int i = 0; i < G[u].size(); i++) { int v = G[u][i].first, w = G[u][i].second; dep[v] = dep[u]+w; dfs(v); sum[u] += sum[v]+1; } path.pop_back();}int main() { memset(sum, 0, sizeof(sum)); int n; cin >> n; for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 2; i <= n; i++) { int t, w; scanf("%d%d", &t, &w); G[t].push_back(make_pair(i, w)); } dep[1] = 0; dfs(1); for(int i = 1; i <= n; i++) printf("%d ", sum[i]); return 0;}
1 0
- 739B Codeforces Alyona and a tree 树上差分+二分(倍增)
- Codeforces 739B Alyona and a tree (树上差分+二分)
- Codeforces 740D Alyona and a tree 二分+树上差分
- codeforces 739b Alyona and a tree
- CODEFORCES 739B Alyona and a tree
- codeforces 739B B. Alyona and a tree
- Codeforces 739B【树上倍增+差分】
- Codeforces Round #381 (Div. 2) D Alyona and a tree(DFS树上搞事)
- CF 739B - Alyona and a tree
- Codeforces 739B(树上路径倍增及差分)
- Codeforces739B. Alyona and a tree(树+二分)
- Codeforces Round #358 (Div. 2) -- C. Alyona and the Tree (树上的DFS)
- CodeForces 381 div.2 D. Alyona and a tree dfs序 二分 区间和
- Codeforces Round #381 (Div. 2) D. Alyona and a tree 树型前缀和+二分维护
- [Codeforces div1] Round 739C. Alyona and towers 线段树+差分数组
- 解题报告:Codeforces Round #381 (Div. 1)B. Alyona and a tree
- Codeforces Round #381 (Div. 1) B Alyona and a tree 树状数组
- Codeforces 739A Alyona and mex(构造)
- VS error LNK2001无法解析的外部符号_CrtDbgReportW
- 【软件安全】使用ollydbg手动修改可执行文件
- 【类加载器】类加载器的原理及其使用方式
- 跟小博老师一起学习数据库 ——函数
- 1
- Codeforces 739B Alyona and a tree (树上差分+二分)
- c#如何获得ModelVisual3D中MeshGeometry3D对象
- 2
- LeetCode 47. Permutations II(生成不同的组合-dfs)
- Android自定义View之View的位置参数
- 题目1155:鸡兔同笼
- 调用Hadoop时遇到的一个问题:could not find or load main class
- 职场必备, Word技巧大全
- NUMA和SMP 架构区别以及对SWAP的影响