传送门

解题思路

  首先对于一个$a$来说,要求$b$和$c$,那么$a,b,c$一定在一条链上。把$b$分类讨论,如果$b$是$a$的祖宗,这个方案数就很好统计了,就是$c$在$a$的子树里随便选,产生的贡献为$(siz_a-1)*(min(k,dep_a))$。如果$b$是$a$的儿子,那么就考虑$b$作为每个点产生的贡献,发现为$siz_x-1$,那么其实要求的就是$[dfn_a+1,dfn_a+siz_a-1]\(中深度为\)[dep_a,dep_a+k]$的点的$siz$之和。发现有两个限制,可以主席树维护。

代码

#include<bits/stdc++.h>

using namespace std;
const int N=300005;
const int M=N*21;
typedef long long LL; inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return f?x:-x;
} int n,q,head[N],cnt,to[N<<1],nxt[N<<1],siz[N],dfn[N],dep[N],num,bl[N];
LL ans; struct Persistence_Segment_Tree{
LL sum[M];int ls[M],rs[M],rt[N],tot;
void build(int &x,int l,int r){
x=++tot; if(l==r) return; int mid=(l+r)>>1;
build(ls[x],l,mid); build(rs[x],mid+1,r);
}
void update(int pre,int &x,int l,int r,int pos,int k){
x=++tot; sum[x]=sum[pre]+k; if(l==r) return;
ls[x]=ls[pre]; rs[x]=rs[pre]; int mid=(l+r)>>1;
if(pos<=mid) update(ls[pre],ls[x],l,mid,pos,k);
else update(rs[pre],rs[x],mid+1,r,pos,k);
}
inline void BUILD(){
build(rt[0],1,n);
for(int i=1;i<=n;i++)
update(rt[i-1],rt[i],1,n,dep[bl[i]],siz[bl[i]]-1);
}
LL query(int u,int v,int l,int r,int L,int R){
if(L<=l && r<=R) return sum[v]-sum[u];
int mid=(l+r)>>1; LL ret=0;
if(L<=mid) ret+=query(ls[u],ls[v],l,mid,L,R);
if(mid<R) ret+=query(rs[u],rs[v],mid+1,r,L,R);
return ret;
}
}tree; inline void add(int bg,int ed){
to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
} void dfs(int x,int F,int d){
dep[x]=d; siz[x]=1; dfn[x]=++num; bl[num]=x;
for(int i=head[x];i;i=nxt[i]){
int u=to[i]; if(u==F) continue;
dfs(u,x,d+1); siz[x]+=siz[u];
}
} int main(){
n=rd(),q=rd(); int x,y;
for(int i=1;i<n;i++){
x=rd(),y=rd();
add(x,y),add(y,x);
}
dfs(1,0,1); tree.BUILD();
while(q--){
x=rd(),y=rd(); ans=(LL)min(dep[x]-1,y)*(siz[x]-1);
ans+=tree.query(tree.rt[dfn[x]],tree.rt[dfn[x]+siz[x]-1],1,n,dep[x],min(n,dep[x]+y));
printf("%lld\n",ans);
}
return 0;
}

BZOJ 3653: 谈笑风生(主席树)的更多相关文章

  1. bzoj 3653 谈笑风生——主席树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3653 原来一直想怎么线段树合并.可是不会把角标挪一位. 查询的其实是子树内一段深度的点的 s ...

  2. bzoj 3653 谈笑风生 —— 主席树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3653 对于一个 (a,b,c),分成 b 是 a 的祖先和 b 在 a 子树里两部分: 第一 ...

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

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

  4. bzoj 3653: 谈笑风生【dfs序+主席树】

    考虑b的两种情况,一种是p的祖先,这种点有min(k,de[p]-1)个,然后每个这种b都有si[p]-1个c点可选: 另一种是p的子孙,要求是在p的子树内且deep在de[p]+1~de[p]+k之 ...

  5. BZOJ.3653.谈笑风生(长链剖分/线段树合并/树状数组)

    BZOJ 洛谷 \(Description\) 给定一棵树,每次询问给定\(p,k\),求满足\(p,a\)都是\(b\)的祖先,且\(p,a\)距离不超过\(k\)的三元组\(p,a,b\)个数. ...

  6. BZOJ 3653: 谈笑风生(离线, 长链剖分, 后缀和)

    题意 给你一颗有 \(n\) 个点并且以 \(1\) 为根的树.共有 \(q\) 次询问,每次询问两个参数 \(p, k\) .询问有多少对点 \((p, a, b)\) 满足 \(p,a,b\) 为 ...

  7. BZOJ 3524 Couriers | 主席树

    BZOJ 3524 Couriers 题意 求一个区间内出现超过区间长度的一半的数,如果没有则输出0. 题解 我可能太菜了吧--这道题愣是没想出来-- 维护权值主席树,记录每个数都出现过多少次: 查询 ...

  8. BZOJ 3653 谈笑风生

    ORZ blutrex...... 主席树. #include<iostream> #include<cstdio> #include<cstring> #incl ...

  9. bzoj 2588 树上主席树

    主席树上树,对于每个节点,继承其父亲的,最后跑f[x]+f[y]-f[lca]-f[fa[lca]] 去重竟然要减一,我竟然不知道?? #include<cstdio> #include& ...

随机推荐

  1. kvm动态修改内存和cpu

    https://www.cnblogs.com/nmap/p/6369180.html

  2. 【原】git命令行查看全部分支与远程分支不同步问题

    git branch -a 查看全部分支 git fetch 重新拉一下分支

  3. linux下载文件到本地命令

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/mengda_lei/article/de ...

  4. Mac版-Jdk安装与环境配置

    下载安装 oracle官网下载,地址:https://www.oracle.com/technetwork/java/javase/downloads/index.html 下载好后,点击安装包,一直 ...

  5. USACO 6.1 章节

    Postal Vans 题目大意 4*n的网格,要经过所有点的有向有环,不重复经过点的路径总数 n<=1000 题解 显然 插头dp 以4为切面 问题是,会发现 超精度 解决呢要么实现高精度,要 ...

  6. LeetCode 102. Binary Tree Level Order Traversal 动态演示

    按层遍历树,要用到queue class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { ...

  7. C语言|博客作业4

    一.本周教学内容:用C语言编写程序-循环结构 2.4 输出华氏-摄氏温度转换表.要求学生掌握使用for循环语句实现指定次数的循环程序设计. 二.本周作业头 问题 答案 这个作业属于哪个内容 C语言程序 ...

  8. VMware Workstation Pro 无法在Windows 上运行 检查可在Windows上运行的此应用的更新版

    1.问题描述 2.排查原因 国庆节后微软推送了一个新的更新补丁,更新之后发现VMware无法打开(未更新前正常). 3.解决方案 3.1卸载微软更新补丁 Windows 10的安全更新难以被彻底规避, ...

  9. jquery 查找元素,id,class

    查找元素下的class 带有.pageactive的a标签 $('a.pageactive') 标签a和..pageactive不要有空格,有空格找不到 ======================= ...

  10. SqlServer 查询所有字段要写说明

    查询出所有未写说明的字段: SELECT IC.table_name TableName, ColName=C.name, PFD.[value] FROM sys.columns C INNER J ...