题目链接:点击查看

题目大意:设 TTT 为一棵有根树,我们做如下的定义:

  • 设 aaa 和 bbb 为 TTT 中的两个不同节点。如果 aaa 是 bbb 的祖先,那么称“aaa 比 bbb 更为厉害”。
  • 设 aaa 和 bbb 为 TTT 中的两个不同节点。如果 aaa 与 bbb 在树上的距离不超过某个给定常数 xxx,那么称“ aaa 与 bbb 彼此彼此”。

给定一棵 nnn 个节点的有根树 TTT,节点的编号为 111 到 nnn,根节点为 111 号节点。
你需要回答 qqq 个询问,询问给定两个整数 ppp 和 kkk,问有多少个有序三元组 (a,b,c)(a,b,c)(a,b,c) 满足:

  1. a,b,ca,b,ca,b,c 为 TTT 中三个不同的点,且 aaa 为 ppp 号节点;
  2. aaa 和 bbb 都比 ccc 更为厉害;
  3. aaa 和 bbb 彼此彼此。这里彼此彼此中的常数为给定的 kkk。

题目分析:读完题后不难看出 aaa 和 bbb 一定都在一条以根为起点的链上,且 ccc 是深度较深的那个点的子树中的一个点,因为点 aaa 已经固定,所以不妨讨论一下 bbb。注意 deep[root]=1deep[root]=1deep[root]=1,sz[u]sz[u]sz[u] 是以点 uuu 为根的子树大小:

  1. 若 deep[b]<deep[a]deep[b]<deep[a]deep[b]<deep[a]:ccc 在点 aaa 的子树中,根据乘法原理计算答案为 min⁡(deep[a]−1,k)∗(sz[a]−1)\min(deep[a]-1,k)*(sz[a]-1)min(deep[a]−1,k)∗(sz[a]−1)
  2. 若 deep[b]>deep[a]deep[b]>deep[a]deep[b]>deep[a]:ccc 在点 bbb 的子树中,所以此时每个点 bbb 的贡献为 sz[b]−1sz[b]-1sz[b]−1

对于情况一可以直接求解,情况二的话这里提供两种思路:

第一种思路就是,我们其实不用关心点 ccc 具体是哪一个,只需要统计 aaa 的子树中 bbb 的贡献即可,所以不妨按照 dfsdfsdfs 序建立主席树,维护的是以深度 deepdeepdeep 为下标的线段树,这样每次查询时,只需要查询 dfsdfsdfs 序在 [L[a],R[a]][L[a],R[a]][L[a],R[a]],下标在 [deep[a]+1,deep[a]+k][deep[a]+1,deep[a]+k][deep[a]+1,deep[a]+k] 中 bbb 节点的 sumsumsum 和即可

到此为止再稍加转换一下第二种思路就出来了,将 dfsdfsdfs 序视为第一维,深度视为第二维,建立一个以 (deep,dfn)(deep,dfn)(deep,dfn) 为维度的二维平面坐标系,然后点 bbb 的可行区间 [deep[a]+1,deep[a]+k][deep[a]+1,deep[a]+k][deep[a]+1,deep[a]+k] 和 [L[a],R[a]][L[a],R[a]][L[a],R[a]] 实际上就是一个矩形,问题就转换为了二维数点问题,就可以愉快的挂上树状数组了

代码:
主席树:

// Problem: P3899 [湖南集训]谈笑风生
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3899
// Memory Limit: 500 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
#include<unordered_map>
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f;
}
template<typename T>
inline void write(T x)
{if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;
struct Node
{int l,r;LL sum;
}tree[N*20];
vector<int>node[N];
int root[N],cnt;
int deep[N],L[N],R[N],sz[N],dfn,n;
void update(int &k,int pos,int val,int l,int r)
{tree[cnt++]=tree[k];k=cnt-1;tree[k].sum+=val;if(l==r) return;int mid=(l+r)>>1;if(pos<=mid) update(tree[k].l,pos,val,l,mid);else update(tree[k].r,pos,val,mid+1,r);
}
LL query(int i,int j,int l,int r,int L,int R) {if(l>r) {return 0;}if(L>r||R<l) {return 0;}if(L>=l&&R<=r) {return tree[j].sum-tree[i].sum;}int mid=(L+R)>>1;return query(tree[i].l,tree[j].l,l,r,L,mid)+query(tree[i].r,tree[j].r,l,r,mid+1,R);
}
void dfs1(int u,int fa,int dep) {L[u]=++dfn;sz[u]=1;deep[u]=dep;for(auto v:node[u]) {if(v==fa) {continue;}dfs1(v,u,dep+1);sz[u]+=sz[v];}R[u]=dfn;
}
void dfs2(int u,int fa) {root[L[u]]=root[L[u]-1];update(root[L[u]],deep[u],sz[u]-1,1,n);for(auto v:node[u]) {if(v==fa) {continue;}dfs2(v,u);}
}
int main()
{#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int m;read(n),read(m);for(int i=1;i<n;i++) {int u,v;read(u),read(v);node[u].push_back(v);node[v].push_back(u);}dfs1(1,0,1);dfs2(1,0);while(m--) {int x,k;read(x),read(k);LL ans=1LL*min(deep[x]-1,k)*(sz[x]-1);ans+=query(root[L[x]-1],root[R[x]],deep[x]+1,min(deep[x]+k,n),1,n);printf("%lld\n",ans);}return 0;
}

二维数点:

// Problem: P3899 [湖南集训]谈笑风生
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3899
// Memory Limit: 500 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
#include<unordered_map>
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f;
}
template<typename T>
inline void write(T x)
{if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=2e6+100;
struct Node {int x,y,type,op,id,val;bool operator<(const Node& t)const {if(x!=t.x) {return x<t.x; } else {return type<t.type;}}
};
vector<Node>q;
vector<int>node[N];
int deep[N],L[N],R[N],sz[N],dfn;
LL c[N],ans[N];
void add(int x,int val) {for(int i=x;i<N;i+=lowbit(i)) c[i]+=val;
}
LL ask(int x) {LL ans=0;for(int i=x;i>0;i-=lowbit(i)) ans+=c[i];return ans;
}
void dfs(int u,int fa,int dep) {L[u]=++dfn;sz[u]=1;deep[u]=dep;for(auto v:node[u]) {if(v==fa) {continue;}dfs(v,u,dep+1);sz[u]+=sz[v];}R[u]=dfn;
}
int main()
{#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int n,m;read(n),read(m);for(int i=1;i<n;i++) {int u,v;read(u),read(v);node[u].push_back(v);node[v].push_back(u);}dfs(1,0,1);for(int i=1;i<=n;i++) {int x=deep[i],y=L[i],val=sz[i]-1;q.push_back({x,y,0,-1,-1,val});}for(int i=1;i<=m;i++) {int x,k;read(x),read(k);int x1=deep[x]+1,x2=min(deep[x]+k,n),y1=L[x],y2=R[x];ans[i]=1LL*min(deep[x]-1,k)*(sz[x]-1);q.push_back({x2,y2,1,1,i,0});q.push_back({x1-1,y1-1,1,1,i,0});q.push_back({x1-1,y2,1,-1,i,0});q.push_back({x2,y1-1,1,-1,i,0});}sort(q.begin(),q.end());for(auto it:q) {if(it.type==1) {//askans[it.id]+=it.op*ask(it.y);} else {//addadd(it.y,it.val);}}for(int i=1;i<=m;i++) {printf("%lld\n",ans[i]);}return 0;
}

洛谷 - P3899 [湖南集训]谈笑风生(dfs序+主席树/二维数点)相关推荐

  1. 洛谷P3899 [湖南集训]谈笑风生

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

  2. 洛谷 - P2163 [SHOI2007]园丁的烦恼(不带修二维数点-树状数组/主席树)

    题目链接:点击查看 题目大意:二维平面坐标系中给出 nnn 个坐标点,然后是 mmm 次询问,每次询问需要回答一个闭合矩阵中有多少个点 题目分析:想挂树套树来着,但是复杂度有点大.本题不带修且可以离线 ...

  3. 洛谷 - P4390 [BOI2007]Mokia 摩基亚(带修二维数点-四叉线段树/CDQ分治)

    题目链接:点击查看 题目大意:给出一个二维平面坐标系,需要执行数次操作,具体操作分为下列两种: 1 x y a:坐标 (x,y)(x,y)(x,y) 加上 aaa 个点 2 x1 y1 x2 y2:查 ...

  4. P3899 [湖南集训]更为厉害(线段树合并、长链剖分、二维数点)

    P3899 [湖南集训]更为厉害 若 deepb<deepa\text{deep}_b<\text{deep}_adeepb​<deepa​:c 在点 a 的子树中,根据乘法原理计算 ...

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

    P3899 [湖南集训]谈笑风生 给定一颗以111号节点为根的树,如果a≠ba \neq ba​=b,且aaa是bbb的祖先,则aaa比bbb更厉害,如果a≠ba \neq ba​=b,且dis( ...

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

    P3899 [湖南集训]谈笑风生 题目描述 Solution 我们考虑离线询问,将询问放在相对应的子树ppp中计算答案. 显然a,b,ca,b,ca,b,c的位置关系有两种情况: bbb是aaa的祖先 ...

  7. P3899 [湖南集训]谈笑风生 主席树解决二维数点

    传送门 文章目录 题意: 思路: 题意: 思路: 由于a,ba,ba,b都比ccc厉害,那么a,ba,ba,b一定是某个是某个的祖先.那么就分为两种情况了: (1)(1)(1) bbb在aaa上面,约 ...

  8. [湖南集训]更为厉害 树上主席树-以树深度为下下标建立主席树

    题意题解: 首先对于树上某个点a来说,假设点b是a的祖先(也就是在a的上面),那么答案很好计算,也就是min(k,dep[a]−1)∗(size[a]−1)min(k,dep[a]-1)*(size[ ...

  9. 洛谷 - P4197 Peaks(Kruskal重构树+dfs序+主席树)

    题目链接:点击查看 题目大意:有 n 座山峰,每座山峰有他的高度 h[ i ] ,有些山峰之间有双向道路相连,共 m 条路径,每条路径有一个困难值,这个值越大表示越难走. 现在有 q 组询问,每组询问 ...

最新文章

  1. JavaScript基础学习--05自定义属性、索引值
  2. zookeeper3.4.6 使用研究
  3. mysql 队列存储_GitHub - hongliangbest/QueueTask: 一个轻量级可拓展的队列任务、暂时支持mysql、redis等存储方式...
  4. 拿到参考资料的预训练模型,太可怕了!
  5. HCIA-RS(211-中文题库,2019最新题库)
  6. mysql汽车租赁管理系统
  7. 偷梁换柱“Windows 11安装包”竟成了恶意程序?
  8. 大数据处理系统,分布式存储系统和分布式计算框架介绍
  9. Gateway 网关路由、断言、过滤
  10. 西南石油大学计算机类云南省分数线,2017西南石油大学各专业分数线
  11. kubeadm重新生成admin.conf
  12. 免费聊天插件 mylivechat
  13. adb 模拟键盘输入、点击屏幕、滑动、按键等操作
  14. Laravel第三方登录开发之实现QQ登录
  15. Web系统大规模并发——电商秒杀与抢购
  16. android 寺库trytry_寺库trytry联手人民日报 以体验感升级共享经济
  17. 唱歌如何保持高位置_什么是高位置发声?
  18. JavaScript:替换原段落中的文字并将其变成红色
  19. CCIE与HCIE那个含金量高些?
  20. 百度AI开发者大会-你是其中一个嘛?百度Create大会(无人驾驶)

热门文章

  1. 突破C++瓶颈,在此一举!
  2. J2SE核心开发实战(一)——认识J2SE
  3. 有多个重载参数pow_随时随地想充就充,同时最多能给三部手机充电的南卡无线充电宝POW-1体验...
  4. MySQL高级 - 锁 - MyISAM表锁 - 小结
  5. MySQL高级 全表扫描更快
  6. 对Spring创建对象的思考
  7. reportInterruptAfterWait
  8. (常用API)正则表达式匹配练习
  9. php递归复制文件内容,PHP递归复制整个文件夹
  10. Spring注解编程基石(二)