Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 753  Solved: 295

Description

设T 为一棵有根树,我们做如下的定义:
• 设a和b为T 中的两个不同节点。如果a是b的祖先,那么称“a比b不知道
高明到哪里去了”。
• 设a 和 b 为 T 中的两个不同节点。如果 a 与 b 在树上的距离不超过某个给定
常数x,那么称“a 与b 谈笑风生”。
给定一棵n个节点的有根树T,节点的编号为1 到 n,根节点为1号节点。你需
要回答q 个询问,询问给定两个整数p和k,问有多少个有序三元组(a;b;c)满足:
1. a、b和 c为 T 中三个不同的点,且 a为p 号节点;
2. a和b 都比 c不知道高明到哪里去了;
3. a和b 谈笑风生。这里谈笑风生中的常数为给定的 k。

Input

输入文件的第一行含有两个正整数n和q,分别代表有根树的点数与询问的个数。接下来n - 1行,每行描述一条树上的边。每行含有两个整数u和v,代表在节点u和v之间有一条边。
接下来q行,每行描述一个操作。第i行含有两个整数,分别表示第i个询问的p和k。

Output

输出 q 行,每行对应一个询问,代表询问的答案。

Sample Input

5 3
1 2
1 3
2 4
4 5
2 2
4 1
2 3

Sample Output


3
1
3

HINT

1<=P<=N

1<=K<=N

N<=300000

Q<=300000

Source

DFS序+可持久化线段树

相比前一道大新闻和后一道图样图森破来说,这题简直太特么友好了……但是膜多了果然有危害,昨天打CF的时候后台开着这题,把分数都续走了……(明明是自己蒻)

图样图森破正解是后缀数组LCP+st表什么的,理论AC,试着用后缀自动机写然而傻傻写不出,弃坑。

b可能是a的祖先也可能是a的子树。前者只需要dep[a]*(size[a]-1)得到答案,后者有些麻烦:对于每一个(a,b)对,答案等于b的子树size,。

刚开始的想法是用DFS序+树状数组统计,敲完DFS序以后开始懵逼,不会用树状数组统计答案……然后想到可持久化线段树。把DFS序作为时间轴,结点深度作为坐标,可以方便地统计出一个结点的所有子结点的size和,也就是后半部分答案。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<queue>
 6 #define LL long long
 7 using namespace std;
 8 const int mxn=300110;
 9 int read(){
10     int x=0,f=1;char ch=getchar();
11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12     while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();}
13     return x*f;
14 }
15 struct edge{int v,nxt;}e[mxn<<1];
16 int hd[mxn],mct=0;
17 void add_edge(int u,int v){
18     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
19 }
20 int dep[mxn],sz[mxn];
21 //
22 int in[mxn],out[mxn];
23 int id[mxn],cnt=0;
24 int n,q;
25 struct node{
26     int l,r;LL sum;
27 }t[mxn*20];
28 int rt[mxn],tct=0;
29 int mx=0;
30 void DFS(int u,int fa){
31     in[u]=++cnt;
32     id[cnt]=u;
33     ++sz[u];
34     dep[u]=dep[fa]+1;
35     mx=max(mx,dep[u]);
36     for(int i=hd[u];i;i=e[i].nxt){
37         int v=e[i].v;
38         if(v==fa)continue;
39         DFS(v,u);
40         sz[u]+=sz[v];
41     }
42     out[u]=cnt;
43 }
44 void update(int p,int v,int l,int r,int x,int &rt){//p为深度
45     rt=++tct;
46     if(x)t[rt]=t[x];
47     t[rt].sum+=v;
48     if(l==r)return;
49     int mid=(l+r)>>1;
50     if(p<=mid)update(p,v,l,mid,t[x].l,t[rt].l);
51     else update(p,v,mid+1,r,t[x].r,t[rt].r);
52     return;
53 }
54 LL query(int L,int R,int l,int r,int rt){
55     if(!rt)return 0;
56     if(L<=l && r<=R){return t[rt].sum;}
57     int mid=(l+r)>>1;
58     LL res=0;
59     if(L<=mid)res+=query(L,R,l,mid,t[rt].l);
60     if(R>mid)res+=query(L,R,mid+1,r,t[rt].r);
61     return res;
62 }
63 int main(){
64     int i,j,u,v;
65     n=read();q=read();
66     for(i=1;i<n;i++){
67         u=read();v=read();
68         add_edge(u,v);
69         add_edge(v,u);
70     }
71     DFS(1,0);
72     for(i=1;i<=cnt;i++){//插入值
73         update(dep[id[i]],sz[id[i]]-1,1,mx,rt[i-1],rt[i]);
74     }
75     while(q--){
76         u=read();v=read();
77         LL ans=query(max(1,dep[u]+1),min(mx,dep[u]+v),1,mx,rt[out[u]]);
78         ans+=(LL)(min(dep[u]-1,v))*(sz[u]-1);
79         ans-=query(max(1,dep[u]+1),min(mx,dep[u]+v),1,mx,rt[in[u]-1]);
80         printf("%lld\n",ans);
81     }
82     return 0;
83 }

转载于:https://www.cnblogs.com/SilverNebula/p/6415960.html

Bzoj3653 谈笑风生相关推荐

  1. BZOJ3653: 谈笑风生

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

  2. COGS 2211. [BZOJ3653]谈笑风生

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

  3. 【总结】一些简单线段树题目的口胡题解

    bzoj1645 离散化+扫描线 tyvj1473 校门外的树3 思维僵化(非要套离线枚举右端点然而不好做)系列,直接容斥求不与[l,r][l,r][l,r]相交的线段个数即可 bzoj3653谈笑风 ...

  4. 【BZOJ3653】谈笑风生 离线+树状数组+DFS序

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

  5. BZOJ3653 洛谷3899:谈笑风生——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3653 https://www.luogu.org/problemnew/show/P3899 设 ...

  6. 【bzoj3653】谈笑风生

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

  7. [BZOJ3653][长链剖分]谈笑风生

    BZOJ3653 我也不知道题面的引申意义 发现可以求出以每个点为p时的ans,讨论一下祖先和子孙的贡献,用长链剖分维护就好了 Code: #include<bits/stdc++.h> ...

  8. [FROM WOJ]#4317 谈笑风生

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

  9. 18岁辍学,22岁进谷歌和Jeff Dean谈笑风生,这样的我究竟需不需要本科文凭?

    机器之心报道 参与:蛋酱.张倩 人生没有固定的答案,但Chris Olah的道路,不一定适合所有人. 假如你年纪轻轻,就有机会进入顶尖的 AI 公司,时常和业内大佬「谈笑风生」,你还会回到大学,努力通 ...

最新文章

  1. 互联网大脑如何产生“梦境“并形成元宇宙
  2. XHProf安装使用笔记
  3. Eclipse安装软件长时间停留在calculating requirements and dependencies
  4. 为什么很多人C语言学不下去
  5. php底层开发框架, yaf,swoole,hiphop
  6. 设计模式——代理模式与装饰模式的异同
  7. 面试 Notes|2021 年秋季 Android 弱鸡艰难求职记。。。
  8. 使用PIL和OpenCV在PC上模拟动画OLED / LCD显示器
  9. VMware-Esxi7.0各个版本镜像文件iso下载链接
  10. Wireshark入门-Wireshark
  11. 拥抱变化,面向Java17,Java8-18全系列特性详解
  12. 【实战】Spring+Spring MVC+Mybatis实战项目之云笔记项目
  13. 查看git HEAD
  14. 摩斯密码(Morse)——python解密
  15. RIP路由项欺骗攻击实验
  16. ESP32在WIN7下USB调试串口驱动安装 解决USB JTAG/serial debug unit (Interface 0)无法安装驱动的问题
  17. android vitamio集成教程,集成Vitamio实现万能播放器(示例代码)
  18. Google出品的Python代码静态类型分析器:Pytype
  19. NV GTX480对ATI HD5870:另一个视角
  20. 2022高压电工上岗证题目及答案

热门文章

  1. 七夕界的浪漫之光,向你安利程序员的表白方式
  2. bcoma 应用程序发生错误_打开网页老是出现《应用程序错误》是怎么回事?
  3. 如何免费下载qq音乐 ----ctf学习之php漏洞
  4. Spring Boot:四大神器之CLI
  5. 李子柒为什么可以火爆全球
  6. 动态像素绘画——StarDust
  7. 微信小程序毕业设计开题报告医院预约挂号小程序+后台管理系统|前后分离VUE.js
  8. Git 配置别名 —— 让命令变得更简单
  9. java实现仿微信app聊天功能_Android仿微信语音聊天功能
  10. 机器人史宾_史宾机器人:重启