题目

给定一棵 n 个点的有根树,另有 q 次询问,每次询问给定
a、k,求有多少个点对 (b, c) 满足 a、b、c 两两不同,a、b 都是
c 的祖先且 a、b 间距离不超过 k。 n, q ≤ 3 × 10^5。

思路

有两种情况。当 b 是 a 的祖先时,b 在 a 的 1 至 k 级祖先
中任选,c 在 a 的子树内任选。
当 b 在 a 子树内时,要求 depb ≤ depa + k,c 在 b 的子树
内任选。可以用主席树(或线段树合并)维护 a 子树内、dep 在
某个区间限制内的 size 和。

代码

#include <cstdio>
#include <algorithm>
#define MAXN 300003
#define MAXM 300003*30
#define ll long long
using namespace std;
int head[MAXN],nxt[MAXN*2],vv[MAXN*2],tot;
inline void add_edge(int u, int v){vv[++tot]=v;nxt[tot]=head[u];head[u]=tot;
}
int cnt;
ll tre[MAXM*2];
int sl[MAXM*2],sr[MAXM*2];
void change(int &x, int l, int r, int pos, int val){if(x==0) x=++cnt;tre[x]+=val;if(l==r) return;int mid=(l+r)>>1;if(pos<=mid) change(sl[x], l, mid, pos, val);else change(sr[x], mid+1, r, pos, val);
}
ll query(int x, int l, int r, int ql, int qr){if(x==0) return 0;if(ql<=l&&r<=qr) return tre[x];int mid=(l+r)>>1;ll res=0;if(ql<=mid) res+=query(sl[x], l, mid, ql, qr);if(mid<qr) res+=query(sr[x], mid+1, r, ql, qr);return res;
}
int merge(int a, int b, int l, int r){if(a==0||b==0) return a+b;int mid=(l+r)>>1;int x=++cnt;tre[x]=tre[a]+tre[b];sl[x]=merge(sl[a], sl[b], l, mid);sr[x]=merge(sr[a], sr[b], mid+1, r);return x;
}
int n,q;
int sz[MAXN],rot[MAXN],dep[MAXN];
void dfs(int u, int fa){sz[u]=1;dep[u]=dep[fa]+1;for(int i=head[u];i;i=nxt[i]){int v=vv[i];if(v==fa) continue;dfs(v, u);sz[u]+=sz[v];}change(rot[u], 1, n, dep[u], sz[u]-1);rot[fa]=merge(rot[fa], rot[u], 1, n);
}
int main(){scanf("%d %d", &n, &q);for(int i=1;i<n;++i){int a,b;scanf("%d %d", &a, &b);add_edge(a, b);add_edge(b, a);}dfs(1, 0);while(q--){int p,k;scanf("%d %d", &p, &k);printf("%lld\n", query(rot[p], 1, n, dep[p]+1, dep[p]+k)+(ll)(sz[p]-1)*min(k, dep[p]-1));}return 0;
}

[BZOJ 3653] 谈笑风生相关推荐

  1. [BZOJ 3653]谈笑风生

    [BZOJ 3653] 谈笑风生 题意 给定一棵 \(n\) 个点根为 \(1\) 单位权值的树以及 \(q\) 个查询, 每次查询给定 \(p\) 和 \(k\), 求满足 \(a,p\) 都是 \ ...

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

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

  3. 【刷题】BZOJ 3653 谈笑风生

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

  4. BZOJ 3653 谈笑风生

    Problem BZOJ 然而是权限题,如果你像蒟蒻我一样没有权限号请上洛谷~ Solution 据说正解是主席树??? 不管了,反正主席树常数巨大,线段树虽然暴力好歹也能卡过去,而且这题数据还比较水 ...

  5. BZOJ 3653: 谈笑风生

    题目在这里呀! 个人认为是一道很好的题目,原来可持久化线段树还能这么用,看题解之前还是没有想到啦要批评!那就写个题解补偿一下? 题意 给你一棵有根树,n个节点,有q次询问,每次询问,给出两个数x(1& ...

  6. BZOJ #3653. 谈笑风生

    题目 题意: 给定一棵树. 询问给定b,kb,kb,k,现在要选择两个距离b≤kb\le kb≤k单位的点a,ca,ca,c,使得a,ba,ba,b都是ccc的祖先. 问总选择方案数. n,q≤3e5 ...

  7. 3653: 谈笑风生

    3653: 谈笑风生 链接 分析: $ans = min(deep[x] - 1, k) * siz[x] - 1 +\sum\limits_{y是u子树内的点}(siz[y] - 1)$ 前面的可以 ...

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

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

  9. 【BZOJ 3653】谈笑风生

    传送门 Problem 给出一个有 nnn 个点的有根树,根节点为 111,边的长度为 111. 有 qqq 个询问,询问给定两个整数 ppp 和 kkk,问有多少个有序三元组 (a,b,c)(a,b ...

最新文章

  1. 技术总监,被判刑12年!因公司未兑现股权,愤怒植入代码,牟利333万
  2. 打印数组算法:堆栈与深度优先搜索(迷宫问题)
  3. hdu 1573(中国剩余定理非互质情况)
  4. WebSen!NT的行业分类说明
  5. laravel increment出现了翻倍递增_股票连续多少个涨停板就可以市值翻倍?
  6. 首次击败美国!2019《财富》世界500强公布:129家中国公司上榜
  7. batch size自适应log(1)
  8. HTML、CSS、JS对unicode字符的不同处理
  9. pandas 作图 统计_pandas数据作图方法
  10. 关于java中的httpsession_JavaWeb——HttpSession
  11. chmod 755 与chmod +x的区别
  12. php爬虫亚马逊,亚马逊爬虫(亚马逊 api)
  13. Java基础 第一节 第一课
  14. 大数据分析图形绘制如何进行?
  15. 记:解决 Weditor 页面元素坐标定位不到、不准确的问题
  16. 基于OpenCV DNN模块给黑白老照片上色(附Python/C++源码)
  17. Python3中StringIO
  18. Python项目对接CAS方案
  19. 嫁给玩股票男人的九大理由
  20. 【JUnit学习笔记】1:使用JUnit4进行简易单元测试的例子

热门文章

  1. java手机号中间4位使用*替换
  2. xp外观主题下载_增强Windows XP外观的简便方法
  3. 100个精选Python实战项目案例,初学者练手必备
  4. 本科三本的计算机博士,读书中的我 从三本本科到985博士
  5. 怎么查看笔记本内存条型号_怎么查看笔记本内存条型号?2种查看笔记本内存型号方法...
  6. android emoji转换成字符串,安卓的emoji表情转换为文字
  7. 骗子网站--正规网赚系统--www.j9m2.com--诈骗网站
  8. 计算机硬盘灯不亮,解决办法:如果计算机硬盘驱动器指示灯不亮,该怎么办?解决电脑硬盘指示灯不亮的问题_IT / computer_资料...
  9. 迅雷再换赛道锁定云计算 盈利能力待考
  10. Uber vs. Lyft