题面

这道题应该比较裸吧。

\(a\),\(b\)都是\(c\)的祖先。

那么第一种情况是\(b\)是\(a\)的祖先,那么方案数就是\(\min\{dep[a]-1,k\}\cdot (num[a]-1)\)。

第二种是\(a\)是\(b\)的祖先,那么方案数是

\[\sum_{c\in subtree(a),dep[c]-dep[a]\leq k} num[c]-1
\]

显然这东西用主席树,一个维度是dfs序,一个维度数深度维护一下就好了吧。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cmath>
  4. #include<cstring>
  5. #define REP(i,a,n) for(register int i(a);i<=(n);++i)
  6. #define FEC(i,x,y) for(register int i=head[x],y=g[i].to;i;i=g[i].ne,y=g[i].to)
  7. #define dbg(...) fprintf(stderr,__VA_ARGS__)
  8. const int SZ=(1<<21)+1;char ibuf[SZ],*iS,*iT,obuf[SZ+128],*oS=obuf,*oT=obuf+SZ-1;
  9. #ifdef ONLINE_JUDGE
  10. #define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SZ,stdin),(iS==iT?EOF:*iS++)):*iS++)
  11. #else
  12. #define gc() getchar()
  13. #endif
  14. template<typename I>inline void read(I&x){char c=gc();int f=0;for(;c<'0'||c>'9';c=gc())c=='-'?f=1:0;for(x=0;c>='0'&&c<='9';c=gc())x=(x<<1)+(x<<3)+(c&15);f?x=-x:0;}
  15. inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}
  16. #define printf(...) (oS>oT&&(flush(),1),oS+=sprintf(oS,__VA_ARGS__))
  17. template<typename A,typename B>inline char SMAX(A&a,const B&b){return a<b?a=b,1:0;}
  18. template<typename A,typename B>inline char SMIN(A&a,const B&b){return a>b?a=b,1:0;}
  19. typedef long long ll;typedef unsigned long long ull;typedef std::pair<int,int>pii;
  20. const int N=300000+7;
  21. int n,Q,x,y,dfn[N],pre[N],dfc,dep[N],num[N],a[N],T;
  22. struct Edge{int to,ne;}g[N<<1];int head[N],tot;
  23. inline void Addedge(int x,int y){g[++tot].to=y;g[tot].ne=head[x];head[x]=tot;}
  24. inline void DFS(int x,int fa=0){
  25. dfn[x]=++dfc;pre[dfc]=x;dep[x]=dep[fa]+1;num[x]=1;
  26. FEC(i,x,y)if(y!=fa)DFS(y,x),num[x]+=num[y];
  27. }
  28. struct Node{int lc,rc,id;ll val;}t[N*21];int RT[N],nod;
  29. inline void Insert(int&o,int L,int R,int x,int k){
  30. if(t[o].id!=T)t[++nod]=t[o],t[o=nod].id=T;t[o].val+=k;if(L==R)return;
  31. int M=(L+R)>>1;x<=M?Insert(t[o].lc,L,M,x,k):Insert(t[o].rc,M+1,R,x,k);
  32. }
  33. inline ll Query(int o,int p,int L,int R,int l,int r){
  34. if(l<=L&&R<=r)return t[o].val-t[p].val;
  35. int M=(L+R)>>1;if(r<=M)return Query(t[o].lc,t[p].lc,L,M,l,r);if(l>M)return Query(t[o].rc,t[p].rc,M+1,R,l,r);
  36. return Query(t[o].lc,t[p].lc,L,M,l,r)+Query(t[o].rc,t[p].rc,M+1,R,l,r);
  37. }
  38. inline char cmp(const int&x,const int&y){return dep[x]<dep[y];}
  39. int main(){
  40. read(n);read(Q);REP(i,1,n-1)read(x),read(y),Addedge(x,y),Addedge(y,x);
  41. DFS(1);REP(i,1,n)a[i]=i;std::sort(a+1,a+n+1,cmp);int p=1;
  42. REP(i,1,n){
  43. ++T;RT[i]=RT[i-1];
  44. while(p<=n&&dep[a[p]]==i)Insert(RT[i],1,n,dfn[a[p]],num[a[p]]-1),++p;//错误笔记:这里的i,p要分清楚不能弄混掉了
  45. }
  46. REP(i,1,Q){
  47. read(x),read(y);//错误笔记:同第49行,i,x要分清楚
  48. printf("%lld\n",std::min(dep[x]-1,y)*(ll)(num[x]-1)+Query(RT[std::min(dep[x]+y,n)],RT[dep[x]],1,n,dfn[x],dfn[x]+num[x]-1));//错误笔记:要把dep[x]+y和n取个min,不然的话还没更新过
  49. }return flush(),0;
  50. }

[BZOJ3653]谈笑风生 主席树的更多相关文章

  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: 谈笑风生(主席树)

    传送门 解题思路 首先对于一个\(a\)来说,要求\(b\)和\(c\),那么\(a,b,c\)一定在一条链上.把\(b\)分类讨论,如果\(b\)是\(a\)的祖宗,这个方案数就很好统计了,就是\( ...

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

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

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

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

  6. 【NOI模拟】谈笑风生(主席树)

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

  7. 数据结构(主席树):COGS 2211. 谈笑风生

    2211. 谈笑风生 ★★★★   输入文件:laugh.in   输出文件:laugh.out   简单对比时间限制:3 s   内存限制:512 MB [问题描述] 设T 为一棵有根树,我们做如下 ...

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

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

  9. BZOJ3653谈笑风生——可持久化线段树+dfs序

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

随机推荐

  1. WinForm、WPF、ASP.NET窗口生命周期

    https://blog.csdn.net/s_521_h/article/details/73826928

  2. QT | 第二章 基本语法

    ''' @Modify Time @Author ------------ ------- python基本语法 2019/10/26 8:16 laoalo ''' import functools ...

  3. [CSP-S模拟测试]:轰炸行动(bomb)(塔尖+拓扑排序+语文)

    题目描述 战狂也在玩<魔方王国>.他只会征兵而不会建城市,因此他决定对小奇的城市进行轰炸.小奇有n座城市,城市之间建立了$m$条有向的地下通道.战狂会发起若干轮轰炸,每轮可以轰炸任意多个城 ...

  4. 继承ConstraintLayout

    开发中复杂的布局基本上都可以通过ConstraintLayout实现,所以我们继承ConstraintLayout实现一个EasyConstraintLayout能够为子view添加圆角和阴影效果. ...

  5. (转)Centos7 yum 源安装nginx

    转:https://www.cnblogs.com/fuhai0815/p/8522868.html 一.建立nginx源 vim /etc/yum.repos.d/nginx.repo [nginx ...

  6. T2691 桶哥的问题——送桶

    这个题其实不难,就是按照结束时候的顺序从大到小走一遍,能送的就送,如果区间不重合就更新一下 代码: #include<iostream> #include<cstdio> #i ...

  7. 第 12 章 python并发编程之协程

    一.引子 主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只用一个)情况下实现并发,并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作 ...

  8. MD5加密 及 防止重复提交

    1.JSP页面 <%@page import="cn.gs.ly.app2.MD5Util"%> <%@page import="java.util.U ...

  9. SEC8 - MySQL 查询语句--------------进阶4:常见的函数

    # 进阶4:常见的函数 /* 概念:将一组逻辑语句封装在方法体中,对外暴露方法名 好处:1.隐藏了实现细节 2.提高代码的复用性 调用: select 函数名() [from 表]; 特点: (1)叫 ...

  10. C# 中定义斜杠 \

    \ 是转义符 如     \’ 单引号    \” 双引号    \\ 反斜杠    \0 空    \a 警告(产生峰鸣)    \b 退格    \f 换页    \n 换行    \r 回车   ...