传送门

解题思路

  首先对于一个$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. ELK7.1.1之插件安装

    在5.0版本之后不支持直接把插件包放入es安装目录的plugin目录下,需要单独安装:而且支持在线安装的插件很少,很多都是需要离线安装.以前的plugin变为elasticsearch-plugin ...

  2. 树结构遍历节点名字提取,这里提取的是el-tree数据结构,封装成函数

    /** * 树形数据提取节点 * @param {*} data */ export function treeDataGetnode (data) { var res = [] var child= ...

  3. BZOJ 3772: 精神污染(dfs序+主席树)

    传送门 解题思路 比较神仙的一道题.首先计算答案时可以每条路径所包含的路径数,对于\(x,y\)这条路径,可以在\(x\)这处开个\(vector\)存\(y\),然后计算时只需要算这个路径上每个点的 ...

  4. wsl和windows相互访问文件夹

    How to access Windows folders from Bash on Ubuntu on Windows You'll find the Windows C:\ structure a ...

  5. 102.kaldi 斯坦福语音识别工具的编译

    接着上一节,在编译完了openFST有限状态机之后,便开始了最重要部分,语音识别插件的编译过程 首先看目录是如下所示的 1.首先添加openBLAS的支持,这是一个矩阵运算库,个人觉得这个矩阵运算库 ...

  6. Python Django 编写一个简易的后台管理工具3-运行项目

    编写view页面 def hello(request): return render(request,'hello.html') 编写html页面 <!DOCTYPE html> < ...

  7. laravel 简单应用 redis

    1.连接配置 database.php 中 测试用 都没做修改 2.创建测试路由及控制器 //添加路由 Route::get('testRedis','RedisController@testRedi ...

  8. 记录Liunx 命令常用的

    df -h 查询硬盘容量(GB方式)

  9. Scrapy框架: 通用爬虫之CrawlSpider

    步骤01: 创建爬虫项目 scrapy startproject quotes 步骤02: 创建爬虫模版 scrapy genspider -t quotes quotes.toscrape.com ...

  10. java异常不匹配问题

    java的异常处理是为了提高程序健壮性的. 当发生异常的时候,我们把这个异常捕获到,或者throw出去.然后对这些异常的情况进行处理.并且异常发生之后的代码仍然会执行,这样就能提高程序的健壮性.如下 ...