#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define per(i,j,k) for(int i=j;i>=k;i--)
#define LL long long
using namespace std;
const int maxx = 3e5+;
struct node{
int l,r;
LL val;
}tree[maxx<<];
int ver[maxx*],Next[maxx*],head[maxx];
///邻接表
int deapth[maxx],Size[maxx],dfn[maxx],root[maxx];
///深度数组 包含自己在内的子节点数目 DFS序 主席树的根
int tot,order,deep,cnt;
///边的序号 DFS序标记 最深深度
void add(int x,int y){
ver[++tot]=y;Next[tot]=head[x];head[x]=tot;
ver[++tot]=x;Next[tot]=head[y];head[y]=tot;
}
void inserts(int l,int r,int pre,int &now,int pos,LL val){
///动态开点部分
now=++cnt;
///把旧的节点的信息更新到新的节点上
tree[now]=tree[pre];
///维护前缀和
tree[now].val+=val;
if (l==r){
return;
}
int mid=(l+r)>>;
if (pos<=mid){
inserts(l,mid,tree[pre].l,tree[now].l,pos,val);
}else {
inserts(mid+,r,tree[pre].r,tree[now].r,pos,val);
}
}
LL query(int L,int R,int l,int r,int ql,int qr){
LL ans=;
///如果在范围内,直接返回
if (ql<=l && r<=qr){
return tree[R].val-tree[L].val;
}
int mid=(l+r)>>;
if(ql<=mid)ans+=query(tree[L].l,tree[R].l,l,mid,ql,qr);
if(qr>mid)ans+=query(tree[L].r,tree[R].r,mid+,r,ql,qr);
return ans;
}
void dfs1(int x,int fa){
Size[x]=;
deapth[x]=deapth[fa]+;
///更新最深是深度
deep=max(deep,deapth[x]);
for(int i=head[x];i;i=Next[i]){
if(ver[i]==fa)continue;
dfs1(ver[i],x);
Size[x]+=Size[ver[i]];
}
}
void dfs2(int x,int fa){
dfn[x]+=++order;
///这里注意,由于我们需要按照树的变量顺序来建立序列,所以应该是root[order-1],root[order]
///size减1是为了减去自己
inserts(,deep,root[order-],root[order],deapth[x],Size[x]-);
for (int i=head[x];i;i=Next[i]){
if(ver[i]==fa)continue;
dfs2(ver[i],x);
}
}
int main(){
int n,q;
int uu,vv,l,r;
while(~scanf("%d%d",&n,&q)){
order=;
deep=;
cnt=;
memset(Next,,sizeof(Next));
memset(Size,,sizeof(Size));
memset(dfn,,sizeof(dfn));
memset(deapth,,sizeof(deapth));
rep(i,,n-){
scanf("%d%d",&uu,&vv);
add(uu,vv);
}
dfs1(,);
dfs2(,);
LL ans=;
int p,k;
while(q--){
scanf("%d%d",&p,&k);
ans=;
///当a点在b点的的下面,那么b所处于的位置,应该是其a的深度和k当中小的那个
///因为b只会在a的上面k个位置,并且如果a的深度太小的话,其深度可能达不到k个
///C的位置的可能一定是a的子节点
ans+=(LL)(Size[p]-)*min(k,deapth[p]-);
///当b点在a的下端,那么c应该在b的子节点中
///所以我们要查询a也就是p的子节点中 所以第一个范围oot[dfn[p]-1],root[dfn[p]+Size[p]-1]
///查询其子节点中深度在deepth[p]+1到death[p]+k的节点中子节点的个数和
///因为我们构架线段树的时候,构建的是前缀和
ans+=query(root[dfn[p]-],root[dfn[p]+Size[p]-],,deep,deapth[p]+,min(deapth[p]+k,deep));
if (deapth[p]==deep)ans=;
printf("%lld\n",ans);
}
}
return ;
}

P3899 [湖南集训]谈笑风生 主席树的更多相关文章

  1. [Luogu P3899] [湖南集训]谈笑风生 (主席树)

    题面 传送门:https://www.luogu.org/problemnew/show/P3899 Solution 你们搞的这道题啊,excited! 这题真的很有意思. 首先,我们可以先理解一下 ...

  2. luogu P3899 [湖南集训]谈笑风生 线段树合并

    Code: #include<bits/stdc++.h> #define maxn 300002 #define ll long long using namespace std; vo ...

  3. 洛谷P3899 [湖南集训]谈笑风生(线段树合并)

    题意 题目链接 Sol 线段树合并板子题,目前我看到两种写法,分别是这样的. 前一种每次需要新建一个节点,空间是\(O(4nlogn)\) 后者不需要新建,空间是\(O(nlogn)\)(面向数据算空 ...

  4. 主席树 || 可持久化线段树 || BZOJ 3653: 谈笑风生 || Luogu P3899 [湖南集训]谈笑风生

    题面:P3899 [湖南集训]谈笑风生 题解: 我很喜欢这道题. 因为A是给定的,所以实质是求二元组的个数.我们以A(即给定的P)作为基点寻找答案,那么情况分两类.一种是B为A的父亲,另一种是A为B的 ...

  5. luogu P3899 [湖南集训]谈笑风生

    传送门 nmyzd,mgdhls,bnmbzdgdnlql,a,wgttxfs 对于一个点\(a\),点\(b\)只有可能是他的祖先或者在\(a\)子树里 如果点\(b\)是\(a\)祖先,那么答案为 ...

  6. P3899 [湖南集训]谈笑风生

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3653 https://www.luogu.org/problemnew/show/P38 ...

  7. 【洛谷 P3899】 [湖南集训]谈笑风生 (主席树)

    题目链接 容易发现\(a,b,c\)肯定是在一条直链上的. 定义\(size(u)\)表示以\(u\)为根的子树大小(不包括\(u\)) 分两种情况, 1.\(b\)是\(a\)的祖先,对答案的贡献是 ...

  8. bzoj 3653 [湖南集训]谈笑风生

    题目描述 设 T 为一棵有根树,我们做如下的定义: • 设 a 和 b 为 T 中的两个不同节点.如果 a 是 b 的祖先,那么称"a 比 b 不知道高明到哪里去了". • 设 a ...

  9. Luogu 3899 [湖南集训]谈笑风生

    BZOJ 3653权限题. 这题方法很多,但我会的不多…… 给定了$a$,我们考虑讨论$b$的位置: 1.$b$在$a$到根的链上,那么这样子$a$的子树中的每一个结点(除了$a$之外)都是可以成为$ ...

随机推荐

  1. python 数据标准化

  2. tcpdump命令介绍

    命令格式为:tcpdump [-nn] [-i 接口] [-w 储存档名] [-c 次数] [-Ae] [-qX] [-r 文件] [所欲捕获的数据内容] 参数: -nn,直接以 IP 及 Port ...

  3. Quick BI取数模型深度剖析

    开发图表最关键的点在于选择准确的图表类型展示准确的数据,而准确的数据往往依赖于一个强大的取数模型,因此设计一个好的取数模型不仅可以解决数据安全的问题,更可以帮助每个访问者高效触达自己想要的数据,开发者 ...

  4. LUOGU 3089 后缀排序(模板)

    传送门 解题思路 这是一个神奇的算法,sa[i]表示排名第i为的元素是啥,rk[i]表示第i个元素排名是啥.然后使用基数排序+倍增的思想去处理.主要是参考的这位大佬的博客(https://www.cn ...

  5. Oracle 行转列及列转行

    参考网址:http://blog.163.com/fushahui_1988@126/blog/static/82879994201192844355174/ 一.多行转一列select id, vn ...

  6. python mooc 3维可视化<第一周第一单元>

    基本含义 数据->图像 分类 重点关注空间数据的可视化 方法 二维标量数据场 三维标量数据场 二位标量数据场 颜色映射法 等值线法 立体图法 层次分割法 三维标量数据场 面绘制法 体绘制法 展示 ...

  7. 2019-8-31-dotnet-core-用值初始化整个数组

    title author date CreateTime categories dotnet core 用值初始化整个数组 lindexi 2019-08-31 16:55:58 +0800 2019 ...

  8. 修改mysql数据库密码的3中方法

    方法1: 用SET PASSWORD命令 mysql -u root mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass ...

  9. NFS实现(双httpd + php-fpm + nfs + mysql 搭建discuz论坛)的方法

    NFS相关介绍 一.NFS简介 1. NFS(Network File System):NFS是一个文件共享协议, 也是是在类Unix系统中在内核中实现的文件系统. 2. 起源:最早是由SUN公司研发 ...

  10. 【JZOJ4770】【NOIP2016提高A组模拟9.9】闭门造车

    题目描述 自从htn体验了一把飙车的快感,他就下定决心要闭门造车!但是他两手空空怎么造得出车来呢?无奈的他只好来到了汽车零部件商店. 一走进商店,玲琅满目的各式零件看得htn眼花缭乱.但是他很快便反应 ...