3653: 谈笑风生
来源:互联网 发布:淘宝接单的app都有哪些 编辑:程序博客网 时间:2024/06/05 12:44
3653: 谈笑风生
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 498 Solved: 185
[Submit][Status][Discuss]
Description
设T 为一棵有根树,我们做如下的定义:
• 设a和b为T 中的两个不同节点。如果a是b的祖先,那么称“a比b不知道
高明到哪里去了”。
• 设a 和 b 为 T 中的两个不同节点。如果 a 与 b 在树上的距离不超过某个给定
常数x,那么称“a 与b 谈笑风生”。
给定一棵n个节点的有根树T,节点的编号为1 到 n,根节点为1号节点。你需
要回答q 个询问,询问给定两个整数p和k,问有多少个有序三元组(a;b;c)满足:
1. a、b和 c为 T 中三个不同的点,且 a为p 号节点;
2. a和b 都比 c不知道高明到哪里去了;
3. a和b 谈笑风生。这里谈笑风生中的常数为给定的 k。
Input
输入文件的第一行含有两个正整数n和q,分别代表有根树的点数与询问的个数。接下来n - 1行,每行描述一条树上的边。每行含有两个整数u和v,代表在节点u和v之间有一条边。
接下来q行,每行描述一个操作。第i行含有两个整数,分别表示第i个询问的p和k。
Output
输出 q 行,每行对应一个询问,代表询问的答案。
Sample Input
5 3
1 2
1 3
2 4
4 5
2 2
4 1
2 3
1 2
1 3
2 4
4 5
2 2
4 1
2 3
Sample Output
3
1
3
HINT
1<=P<=N
1<=K<=N
N<=300000
Q<=300000
Source
维护dfs序的线段树
每次询问的b要么在a上面(每组的权值是size[a])要么在a下面(每组权值size[b])
然后距离都不超过k
第一种很好处理
第二种在线段树一段区间里面还需满足深度符合
也就是线段树需要两个关键字判断(dfs序与深度)
这样的询问每次是O(log^2)的
一开始也不知道为什么想bfs序?显然不可以
然后query函数里面没及时return 0
#include<iostream>#include<cstdio>#include<queue>#include<vector>using namespace std;const int maxn = 4E5 + 30;typedef long long LL;int n,m,p,k,clo,dfi[maxn],dfo[maxn],siz[maxn],L[maxn];LL c[maxn*20];int ac[maxn*20],bc[maxn*20];vector <int> v[maxn];void build(int o,int l,int r,int pos,int Add,int de){if (l == r) {c[o] = Add; ac[o] = bc[o] = de; return;}int mid = (l+r) >> 1;if (pos <= mid) build(2*o,l,mid,pos,Add,de);else build(2*o+1,mid+1,r,pos,Add,de);c[o] = c[2*o] + c[2*o+1];ac[o] = min(ac[2*o],ac[2*o+1]);bc[o] = max(bc[2*o],bc[2*o+1]);}void dfs(int k){dfi[k] = ++clo; for (int i = 0; i < v[k].size(); i++) {int to = v[k][i];if (L[to]) continue;L[to] = L[k] + 1;dfs(to);siz[k] += siz[to] + 1;}dfo[k] = clo;build(1,1,n,dfi[k],siz[k],L[k]);}LL query(int o,int l,int r,int ql,int qr,int qa,int qb){if (ql <= l && r <= qr && qa <= ac[o] && bc[o] <= qb) return c[o];if (bc[o] < qa || qb < ac[o]) return 0;int mid = (l+r) >> 1; LL ret = 0;if (ql <= mid) ret += query(2*o,l,mid,ql,qr,qa,qb);if (qr > mid) ret += query(2*o+1,mid+1,r,ql,qr,qa,qb);return ret;}int main(){#ifdef YZYfreopen("yzy.txt","r",stdin);#endifcin >> n >> m; for (int i = 1; i < n; i++) {int x,y; scanf("%d%d",&x,&y);v[x].push_back(y); v[y].push_back(x);}clo = 0; L[1] = 1; dfs(1); while (m--) {int p,k; LL ans; scanf("%d%d",&p,&k);if (L[p] - k >= 1) ans = 1LL*k*1LL*siz[p];else ans = 1LL*(L[p]-1)*1LL*siz[p];if (dfi[p] + 1 <= dfo[p]) ans += query(1,1,n,dfi[p]+1,dfo[p],L[p] + 1,L[p] + k);printf("%lld\n",ans);}return 0;}
0 0
- 3653: 谈笑风生
- 【BZOJ 3653】 谈笑风生|主席树
- bzoj 3653: 谈笑风生 (主席树+dfs序)
- BZOJ3653: 谈笑风生
- bzoj3653: 谈笑风生
- BZOJ3653: 谈笑风生
- 【bzoj3653】谈笑风生
- 【bzoj3653】谈笑风生
- bzoj3653&cogs2211 谈笑风生
- [bzoj3653]谈笑风生 主席树
- 【2014-7】day3 T2 谈笑风生
- [未完待续][NOI2017模拟]谈笑风生
- 【BZOJ3653】谈笑风生【主席树】【DFS序】
- 【bzoj3653】【谈笑风生】【dfs序+主席树】
- 老码农教你在 StackOverflow 上谈笑风生
- 程序员遇上禅师,该如何谈笑风生
- csu 1950: 谈笑风生 卡特兰数
- 谈笑风生线段树(点修改)
- Git学习记录
- HDOJ4857【拓扑排序】
- 剑指Offer——求1-n的和值
- windows下使用adb工具查看android程序cpu和内存消耗情况
- Java开发使用Excel批量导入数据
- 3653: 谈笑风生
- TreeSet去重字符串
- [C++]广度优先搜索(含C++模板)
- sublime 整合 eslint
- CDN介绍
- maven pom文件详解
- 【mysql】order by 优化与索引的应用
- 深入Java集合学习系列:LinkedHashMap的实现原理
- FragmentTransaction add 和 replace 区别