传送门

解题思路

  首先对于一个$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$之和。发现有两个限制,可以主席树维护。

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=300005;
  4. const int M=N*21;
  5. typedef long long LL;
  6. inline int rd(){
  7. int x=0,f=1;char ch=getchar();
  8. while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
  9. while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
  10. return f?x:-x;
  11. }
  12. int n,q,head[N],cnt,to[N<<1],nxt[N<<1],siz[N],dfn[N],dep[N],num,bl[N];
  13. LL ans;
  14. struct Persistence_Segment_Tree{
  15. LL sum[M];int ls[M],rs[M],rt[N],tot;
  16. void build(int &x,int l,int r){
  17. x=++tot; if(l==r) return; int mid=(l+r)>>1;
  18. build(ls[x],l,mid); build(rs[x],mid+1,r);
  19. }
  20. void update(int pre,int &x,int l,int r,int pos,int k){
  21. x=++tot; sum[x]=sum[pre]+k; if(l==r) return;
  22. ls[x]=ls[pre]; rs[x]=rs[pre]; int mid=(l+r)>>1;
  23. if(pos<=mid) update(ls[pre],ls[x],l,mid,pos,k);
  24. else update(rs[pre],rs[x],mid+1,r,pos,k);
  25. }
  26. inline void BUILD(){
  27. build(rt[0],1,n);
  28. for(int i=1;i<=n;i++)
  29. update(rt[i-1],rt[i],1,n,dep[bl[i]],siz[bl[i]]-1);
  30. }
  31. LL query(int u,int v,int l,int r,int L,int R){
  32. if(L<=l && r<=R) return sum[v]-sum[u];
  33. int mid=(l+r)>>1; LL ret=0;
  34. if(L<=mid) ret+=query(ls[u],ls[v],l,mid,L,R);
  35. if(mid<R) ret+=query(rs[u],rs[v],mid+1,r,L,R);
  36. return ret;
  37. }
  38. }tree;
  39. inline void add(int bg,int ed){
  40. to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
  41. }
  42. void dfs(int x,int F,int d){
  43. dep[x]=d; siz[x]=1; dfn[x]=++num; bl[num]=x;
  44. for(int i=head[x];i;i=nxt[i]){
  45. int u=to[i]; if(u==F) continue;
  46. dfs(u,x,d+1); siz[x]+=siz[u];
  47. }
  48. }
  49. int main(){
  50. n=rd(),q=rd(); int x,y;
  51. for(int i=1;i<n;i++){
  52. x=rd(),y=rd();
  53. add(x,y),add(y,x);
  54. }
  55. dfs(1,0,1); tree.BUILD();
  56. while(q--){
  57. x=rd(),y=rd(); ans=(LL)min(dep[x]-1,y)*(siz[x]-1);
  58. ans+=tree.query(tree.rt[dfn[x]],tree.rt[dfn[x]+siz[x]-1],1,n,dep[x],min(n,dep[x]+y));
  59. printf("%lld\n",ans);
  60. }
  61. return 0;
  62. }

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. webbrowser控件显示word文档

    参照某网站上的步骤(http://www.kuqin.com/office/20070909/968.html)首先,在Visual Studio中创建一个C#语言的Windows应用程序,然后在左侧 ...

  2. [CSP-S模拟测试]:mine(DP)

    题目描述 有一个$1$维的扫雷游戏,每个格子用$*$表示有雷,用$0/1/2$表示无雷并且相邻格子中有$0/1/2$个雷.给定一个仅包含$?$.$*$.$0$.$1$.$2$的字符串$s$,问有多少种 ...

  3. Cent OS (三)vi文本编辑操作

    序号 命令 命令含义 1 echo            2 vi/vim    编辑 3 cat     cat 命令用于连接文件并打印到标准输出设备上. 4 more   分屏显示文本内容 5 l ...

  4. Unity Shader之模板测试

    Unity Shader之模板测试 一沙一世界,一花一天堂 一.Stencil testing 渲染管线     当片段着色器处理完一个片段之后,模板测试(Stencil Test)会开始执行,和深度 ...

  5. 用倍增法构造后缀数组中的SA及RANK数组

    感觉后缀数组很难学的说= = 不过总算是啃下来了 首先 我们需要理解一下倍增法构造的原理 设原串的长度为n 对于每个子串 我们将它用'\0'补成长度为2^k的串(2^k-1<n<=2^k) ...

  6. APP运营怎么利用留存率等数据分析用户减少的原因?

    APP运营怎么利用留存率等数据分析用户减少的原因? 数据分析最核心的方法是作比较,因为绝对的数值在大多数场合下是没有意义的,通过在不同维度之间做数据的比较分析,能帮助开发者找到数据变化的原因.举一个典 ...

  7. USACO 6.3 章节 你对搜索和剪枝一无所知QAQ

    emmm........很久很久以前 把6.2过了 所以emmmmmm 直接跳过 ,从6.1到6.3吧 Fence Rails 题目大意 N<=50个数A1,A2... 1023个数,每个数数值 ...

  8. FWT公式一览

    总表 真值表 对应运算 FWT IFWT A=B=0 A≠B A=B=1 左项 右项 左项 右项 0 0 1 & L+R R L-R R 0 1 0 ^ L+R L-R (L+R)/2 (L- ...

  9. Yii 1.1 cookie删不掉

    我的cookie是这样设置的: $cookie = new CHttpCookie('username','Jack'); $cookie->expire = time()+60*60*24*3 ...

  10. .NET Core TDD 前传: 编写易于测试的代码 一 -- 缝

    转载于: https://www.cnblogs.com/cgzl/p/9365955.html 有时候不是我们不想做单元测试, 而是这代码写的实在是没法测试.... 举个例子, 如果一辆汽车在产出后 ...