#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. makefile 语法笔记 3

    这里说明了 在一些情况下 这也是可以使用通配符的 objects =*.o 这种情况是不会展开的 makefile 中的变量是C++/C 中的宏 如果希望展开,可以使用 $(wildcard *.o) ...

  2. wordpress设置一个特定的页面作为首页

    首先在"页面"里新建一个页面,比如标题为"welcome"; 然后在设置里找到"阅读",首页显示调整为"一个静态页面", ...

  3. JS---案例:手风琴 (利用封装好的动画函数)

    案例:手风琴     封装好的动画函数在common.js里面     //function getStyle(element, attr) {...}     //function animate( ...

  4. OpenLayers使用点要素作为标记

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head ...

  5. Freckles (最小生成树)

    #include<iostream> #include<cstring> #include<stdio.h> #include<queue> #incl ...

  6. 【JZOJ5086】【GDOI2017第四轮模拟day1】数列 折半搜索

    题面 有一个长度为n 的排列,现在有一些位置的数已经模糊不清了,你只知道这个排列的逆序对个数是K,你能计算出总共有多少可能的排列吗? 对于100% 的数据,n <=10^3,K<=10^9 ...

  7. JPA 将驼峰列名自动转换为_

    数据库中和代码中都没有'cat_age'列名:但是用jpa保存的时候,总是提示此错误:这个问题纠结半天,后来在朋友的指点下,找到问题所在: spring data  jpa 使用默认策略是Improv ...

  8. linux系统 (实验一)实验楼的课程笔记

    实验楼的课程笔记 tab 键是命令补全 输入 tail  find / 立刻卡住 这时候ctrl+c 可以终端当前指令 一些常用的指令 Ctrl+d 键盘输入结束或退出终端 Ctrl+s 暂停当前程序 ...

  9. MaxCompute技术人背后的故事:从ApacheORC到AliORC

    2019大数据技术公开课第一季<技术人生专访>来袭,本季将带领开发者们探讨大数据技术,分享不同国家的工作体验.本文整理自阿里巴巴计算平台事业部高级技术专家吴刚的专访,将为大家介绍Apach ...

  10. qt绘制渐变区域

    // 原理:通过点到线,然后叠加成区域.同理,可使用其他图形 QPainter painter(m_pWidget); QLinearGradient linearGradient(QPointF(, ...