bzoj 3653 [湖南集训]谈笑风生
题目描述
设 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) 满足:
a、 b 和 c 为 T 中三个不同的点,且 a 为 p 号节点;
a 和 b 都比 c 不知道高明到哪里去了;
- a 和 b 谈笑风生。这里谈笑风生中的常数为给定的 k。
输入输出格式
输入格式:
输入文件的第一行含有两个正整数 n 和 q,分别代表有根树的点数与询问的个数。
接下来 n − 1 行,每行描述一条树上的边。每行含有两个整数 u 和 v,代表在节点 u 和 v 之间有一条边。
接下来 q 行,每行描述一个操作。第 i 行含有两个整数,分别表示第 i 个询问的 p 和 k。
输出格式:
输出 q 行,每行对应一个询问,代表询问的答案。
输入输出样例
5 3
1 2
1 3
2 4
4 5
2 2
4 1
2 3
3
1
3
说明
样例中的树如下图所示:
对于第一个和第三个询问,合法的三元组有 (2,1,4)、 (2,1,5) 和 (2,4,5)。
对于第二个询问,合法的三元组只有 (4,2,5)。
所有测试点的数据规模如下:
对于全部测试数据的所有询问, 1 ≤ p ≤ n, 1 ≤ k ≤ n.
今天是长者的生日,所以要谈笑风生。。。
首先a是固定的,那么分两种情况讨论b的位置:
1.b是a的祖先,这样的贡献是:
2.b在a的子树内,且b是c的祖先,那么我们枚举每一个可能的深度计算答案,那么贡献为:
(size-1是因为要三个点不同)
也就是要维护某个深度的size和,然后因为有dfn的限制,我们可以用可持久化线段树来实现维护。。。
那么我们按照dfn来建主席树,主席树以deep为值域,然后询问就是在主席树上区间求和即可。。。
// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=600050;
int to[N],nxt[N],head[N],cnt;
int dfn[N],ed[N],tt,size[N],deep[N],xh[N];
int rt[N*20],rs[N*20],ls[N*20],sz,n,q;
ll sum[N*20];
void lnk(int x,int y){
to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;
to[++cnt]=x,nxt[cnt]=head[y],head[y]=cnt;
}
void dfs(int x,int f){
size[x]=1;deep[x]=deep[f]+1;dfn[x]=++tt,xh[tt]=x;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];if(y==f) continue;dfs(y,x);size[x]+=size[y];
}
ed[x]=tt;
}
void insert(int x,int &y,int l,int r,int id,int v){
y=++sz;ls[y]=ls[x];rs[y]=rs[x];sum[y]=sum[x];
if(l==r){sum[y]+=v;return;}
int mid=(l+r)>>1;
if(id<=mid) insert(ls[x],ls[y],l,mid,id,v);
else insert(rs[x],rs[y],mid+1,r,id,v);
sum[y]=sum[ls[y]]+sum[rs[y]];
}
ll query(int x,int y,int l,int r,int xl,int xr){
if(xl<=l&&r<=xr) return sum[y]-sum[x];
int mid=(l+r)>>1;
if(xr<=mid) return query(ls[x],ls[y],l,mid,xl,xr);
else if(xl>mid) return query(rs[x],rs[y],mid+1,r,xl,xr);
else return query(ls[x],ls[y],l,mid,xl,mid)+query(rs[x],rs[y],mid+1,r,mid+1,xr);
}
int main(){
scanf("%d%d",&n,&q);
for(int i=1;i<n;i++){
int u,v;scanf("%d%d",&u,&v);lnk(u,v);
}
dfs(1,1);
for(int i=1;i<=tt;i++) insert(rt[i-1],rt[i],1,2*n,deep[xh[i]],size[xh[i]]-1);
for(int i=1;i<=q;i++){
int x,k;scanf("%d%d",&x,&k);
ll ans=1ll*min(deep[x]-1,k)*(size[x]-1);
ans+=query(rt[dfn[x]-1],rt[ed[x]],1,2*n,deep[x]+1,deep[x]+k);
printf("%lld\n",ans);
}
return 0;
}
bzoj 3653 [湖南集训]谈笑风生的更多相关文章
- 主席树 || 可持久化线段树 || BZOJ 3653: 谈笑风生 || Luogu P3899 [湖南集训]谈笑风生
题面:P3899 [湖南集训]谈笑风生 题解: 我很喜欢这道题. 因为A是给定的,所以实质是求二元组的个数.我们以A(即给定的P)作为基点寻找答案,那么情况分两类.一种是B为A的父亲,另一种是A为B的 ...
- Luogu 3899 [湖南集训]谈笑风生
BZOJ 3653权限题. 这题方法很多,但我会的不多…… 给定了$a$,我们考虑讨论$b$的位置: 1.$b$在$a$到根的链上,那么这样子$a$的子树中的每一个结点(除了$a$之外)都是可以成为$ ...
- luogu P3899 [湖南集训]谈笑风生
传送门 nmyzd,mgdhls,bnmbzdgdnlql,a,wgttxfs 对于一个点\(a\),点\(b\)只有可能是他的祖先或者在\(a\)子树里 如果点\(b\)是\(a\)祖先,那么答案为 ...
- P3899 [湖南集训]谈笑风生
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3653 https://www.luogu.org/problemnew/show/P38 ...
- luogu P3899 [湖南集训]谈笑风生 线段树合并
Code: #include<bits/stdc++.h> #define maxn 300002 #define ll long long using namespace std; vo ...
- 洛谷P3899 [湖南集训]谈笑风生(线段树合并)
题意 题目链接 Sol 线段树合并板子题,目前我看到两种写法,分别是这样的. 前一种每次需要新建一个节点,空间是\(O(4nlogn)\) 后者不需要新建,空间是\(O(nlogn)\)(面向数据算空 ...
- 【洛谷 P3899】 [湖南集训]谈笑风生 (主席树)
题目链接 容易发现\(a,b,c\)肯定是在一条直链上的. 定义\(size(u)\)表示以\(u\)为根的子树大小(不包括\(u\)) 分两种情况, 1.\(b\)是\(a\)的祖先,对答案的贡献是 ...
- P3899 [湖南集训]谈笑风生 主席树
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> ...
- [Luogu P3899] [湖南集训]谈笑风生 (主席树)
题面 传送门:https://www.luogu.org/problemnew/show/P3899 Solution 你们搞的这道题啊,excited! 这题真的很有意思. 首先,我们可以先理解一下 ...
随机推荐
- android动画基础之Animation
android 动画 摘要: 概述 最近总结一下Android的一些东西,毕竟基础不牢地动山摇.本篇主要涉及Animation,对Tween和Frame动画做些总结. Tween Tween动画即补间 ...
- 日志的艺术(The art of logging)
程序员学习每一门语言都是从打印“hello world”开始的,日志也是新手程序员学习.调试程序的一大利器.当项目上线之后,也会有各种各样的日志,比如记录用户的行为.服务器的状态.异常情况等等.打印日 ...
- [epub] epub.js的ePubReader函数报URI malformed错误的解决办法
报错信息:URI malformed 今天遇到了一个奇怪的问题折腾三个小时,最后发现是作者在底层使用了decodeURIComponent进行URL解码,而我在应用层使用了escape/unescap ...
- win7及以上系统打开chm空白或显示"无法打开"的2个解决方案
1:在文件上右键单击属性.选择解锁. 2:确保文件路径中没有特殊字符.比如"#".如果路径中存在特殊字符,chm文件可能找不到路径而无法显示.如 d:\资料\c#\***.chm. ...
- hdu 2586 How far away ?倍增LCA
hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增 ...
- 51Nod 1267 4个数和为0 二分
给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出"Yes",否则输出"No".Input第1行,1个数N,N为数组的长度(4 <= ...
- MySql的隔离级别和锁的关系
一.事务的4个基本特征 Atomic(原子性): 事务中包括的操作被看做一个逻辑单元.这个逻辑单元中的操作要 么所有成功.要么所有失败. Consistency(一致性): 仅仅有合法的数据能 ...
- 数据结构(C实现)------- 最小生成树之Prim算法
[本文是自己学习所做笔记.欢迎转载.但请注明出处:http://blog.csdn.net/jesson20121020] 算法描写叙述 假设连通图是一个网,则称该网中全部生成树中权值总和最小的生成树 ...
- 【LDA】修正 GibbsLDA++-0.2 中的两个内存问题
周末这两天在家用LDA做个小实验. 在LDA的众多实现的工具包中.GibbsLDA 是应用最广泛的.包含c++版本号.java版本号等.GibbsLDA++ 是它的C++版本号的实现.眼下最新版本号是 ...
- Simple prefix compression
题目 看懂题目的意思 直接模拟就能够了 好像不用递归就能够了. . 尽管这周学的是递归 还是偷了一些懒 直接模拟 在说这个题目的意思 本来能够写的非常清楚的下标 题目非要把两个字符串的表示方法写的这 ...