题目链接

https://www.lydsy.com/JudgeOnline/problem.php?id=3653

https://www.luogu.org/problemnew/show/P3899

思路

三个点肯定在1到c的链上

a已经确定

1.b是a的祖先,答案就是(siz[u]-1)*min(dis[u]-1,k)

2.a是b的祖先,要求\(1<=dis[b]-dis[a]<=k\)

\(1+dis[a]<=dis[b]<=k+dis[a]\)

第一问可以快速求出

第二问无脑线段树合并

代码

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. #define it_ll vector<ll>::iterator
  4. #define it_pair vector<pair<ll,ll> >::iterator
  5. using namespace std;
  6. const ll N=3e5+7;
  7. ll read() {
  8. ll x=0,f=1;char s=getchar();
  9. for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
  10. for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
  11. return x*f;
  12. }
  13. ll n,m,dis[N],siz[N];
  14. vector<pair<ll,ll> > Q[N];
  15. vector<ll> G[N];
  16. void dfs(ll u,ll f) {
  17. dis[u]=dis[f]+1;
  18. siz[u]=1;
  19. for(it_ll it=G[u].begin();it!=G[u].end();++it) {
  20. if(*it==f) continue;
  21. dfs(*it,u);
  22. siz[u]+=siz[*it];
  23. }
  24. }
  25. namespace seg {
  26. struct node {
  27. ll ls,rs,tot;
  28. }e[N*30];
  29. ll cnt;
  30. void insert(ll &rt,ll l,ll r,ll id,ll k) {
  31. if(!rt) rt=++cnt;
  32. e[rt].tot+=k;
  33. if(l==r) return;
  34. ll mid=(l+r)>>1;
  35. if(id<=mid) insert(e[rt].ls,l,mid,id,k);
  36. else insert(e[rt].rs,mid+1,r,id,k);
  37. }
  38. ll query(ll rt,ll l,ll r,ll L,ll R) {
  39. if(L<=l&&r<=R) return e[rt].tot;
  40. ll mid=(l+r)>>1;
  41. if(L<=mid&&R>mid) return query(e[rt].ls,l,mid,L,R)+query(e[rt].rs,mid+1,r,L,R);
  42. if(L<=mid) return query(e[rt].ls,l,mid,L,R);
  43. if(R>mid) return query(e[rt].rs,mid+1,r,L,R);
  44. }
  45. ll merge(ll x,ll y){
  46. if(!x||!y) return x+y;
  47. e[x].tot+=e[y].tot;
  48. e[x].ls=merge(e[x].ls,e[y].ls);
  49. e[x].rs=merge(e[x].rs,e[y].rs);
  50. return x;
  51. }
  52. }
  53. ll rt[N];
  54. ll ans[N];
  55. ll solve(ll u,ll f) {
  56. seg::insert(rt[u],1,n,dis[u],siz[u]-1);
  57. for(it_ll it=G[u].begin();it!=G[u].end();++it) {
  58. if(*it==f) continue;
  59. solve(*it,u);
  60. rt[u]=seg::merge(rt[u],rt[*it]);
  61. }
  62. for(it_pair it=Q[u].begin();it!=Q[u].end();++it) {
  63. ans[it->second]=1LL*seg::query(rt[u],1,n,dis[u]+1,dis[u]+it->first)+1LL*(siz[u]-1)*min(dis[u]-1,it->first);
  64. // cout<<seg::e[seg::e[rt[u]].rs].tot<<" ["<<dis[u]+1<<", "<<dis[u]+it->first<<"]\n";
  65. // cout<<1LL*seg::query(rt[u],1,n,dis[u]+1,dis[u]+it->first)<<"\n";
  66. }
  67. }
  68. int main() {
  69. n=read(),m=read();
  70. for(ll i=1;i<n;++i) {
  71. ll x=read(),y=read();
  72. G[x].push_back(y),G[y].push_back(x);
  73. }
  74. for(ll i=1;i<=m;++i) {
  75. ll p=read(),k=read();
  76. Q[p].push_back(make_pair(k,i));
  77. }
  78. dfs(1,0);
  79. solve(1,0);
  80. for(ll i=1;i<=m;++i) printf("%lld\n",ans[i]);
  81. return 0;
  82. }

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

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

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

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

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

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

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

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

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

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

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

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

    #include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> ...

  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. Protobuf数据类型

    protobuf编译文件和源码在点击打开链接 1:   数据类型: double: 浮点数 float: 单精度浮点 int32: int类型,使用可变长编码,编码负数不够高效,如果有负数那么使用si ...

  2. sitecore系列教程之如何以编程方式将访客数据关联到联系人卡片

      在我之前关于Sitecore体验资料的帖子中,我们看到了我们如何了解访问者的一切,包括访问他们在访问期间触发的事件.在这篇博客文章中,我将引导您完成识别匿名用户并将用户访问与联系人记录联系起来的过 ...

  3. Teacher Bo (时间复杂度 + 暴力)

    如果你仔细看就会发现有一个数据很重要那就是点的范围,那么这样一来最多只有2 * maxn的不同曼哈顿距离了,这样一看只要暴力一下就可以过了. #include<bits/stdc++.h> ...

  4. Acperience (英语阅读 + 数学推导)

    #include<bits/stdc++.h> using namespace std; int main(){ int T,n,m;scanf("%d",&T ...

  5. uvalive 5731 Qin Shi Huang’s National Road System

    题意: 秦始皇要修路使得所有的城市连起来,并且花费最少:有一个人,叫徐福,他可以修一条魔法路,不花费任何的钱与劳动力. 秦始皇想让修路的费用最少,但是徐福想要受益的人最多,所以他们经过协商,决定让 A ...

  6. Qt 添加 QtNetwork 库文件

    Qt应用程序默认没有加QtNetwork库.如下图: 在开发过程中,因处理业务需要手动添加QtNetwork库.根据常见情况分为以下两种: [1]若使用QTCreator开发程序 在工程的pro文件中 ...

  7. 刨根究底字符编码之—UTF-16编码方式

    在网上已经转悠好几天了, 这篇文章让我知道了UTF-16的前世今生, 感谢作者https://cloud.tencent.com/developer/article/1384687 1. UTF-16 ...

  8. 写自动更新程序出现"远程服务器返回错误: (404) 未找到"

    在win2003配置后,在客户端运行时能够下载exe和dll文件,但是在更新lib文件时总是报“远程服务器返回错误: (404) 未找到”错误,不明白咋会出现这个问题,去网上一查,发现以下解决办法: ...

  9. Hive 的排名和跨行 窗口函数及其使用

    一.排序&去重分析 row_number() over(partititon by col1 order by col2) as rn 也可以用 row_number() over(distr ...

  10. pyspider源码解读--调度器scheduler.py

    pyspider源码解读--调度器scheduler.py scheduler.py首先从pyspider的根目录下找到/pyspider/scheduler/scheduler.py其中定义了四个类 ...