博客
关于我
P3899 [湖南集训]谈笑风生 主席树解决二维数点
阅读量:275 次
发布时间:2019-03-01

本文共 3322 字,大约阅读时间需要 11 分钟。

文章目录

题意:

在这里插入图片描述

思路:

由于 a , b a,b a,b都比 c c c厉害,那么 a , b a,b a,b一定是某个是某个的祖先。那么就分为两种情况了:

( 1 ) (1) (1) b b b a a a上面,约定 d e p t h [ 1 ] = 1 depth[1]=1 depth[1]=1,此时答案显然为 m i n ( d e p t h [ a ] − 1 , k ) ∗ ( s e [ a ] − 1 ) min(depth[a]-1,k)*(se[a]-1) min(depth[a]1,k)(se[a]1)
( 2 ) (2) (2) b b b a a a的下下面,这个时候就不是那么容易搞了,问题转化成我们要求 a a a这个子树中 d e p t h depth depth范围在 [ d e p t h [ a ] + 1 , d e p t h [ a ] + k ] [depth[a]+1,depth[a]+k] [depth[a]+1,depth[a]+k]内的所有点的 s e [ i ] − 1 se[i]-1 se[i]1,先考虑暴力怎么写呢?显然我们可以暴力对这颗子树的深度建线段树,这样就变成了区间查询的问题了。而这样复杂度是肯定不行的,所以我们考虑建可持久化线段树,根据树的 d f s dfs dfs序建主席树,以节点深度为下标,那么查询就变成了 q u e r y ( r o o t [ d f n [ p ] ] , r o o t [ d f n [ p ] + s e [ p ] − 1 ] , 1 , n , d e p t h [ p ] + 1 , m i n ( d e p t h [ p ] + k , n ) ) query(root[dfn[p]],root[dfn[p]+se[p]-1],1,n,depth[p]+1,min(depth[p]+k,n)) query(root[dfn[p]],root[dfn[p]+se[p]1],1,n,depth[p]+1,min(depth[p]+k,n)),再加上 ( 1 ) (1) (1)的答案即可。

我们还可以将其转换成二维数点的问题。

通过以上分析不难发现我们要找的点就是
深度范围是 [ d e p t h [ p ] + 1 , d e p t h [ p ] + k ] [depth[p]+1,depth[p]+k] [depth[p]+1,depth[p]+k] d f s dfs dfs序范围是 [ d f n [ p ] , d f n [ p ] + s e [ p ] − 1 ] [dfn[p],dfn[p]+se[p]-1] [dfn[p],dfn[p]+se[p]1],那么我们以深度建立 x x x轴,以 d f s dfs dfs序建立 y y y轴,让后统计就好啦。

主席树 O ( n l o g n ) O(nlogn) O(nlogn)

//#pragma GCC optimize(2)#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define X first#define Y second#define L (u<<1)#define R (u<<1|1)#define pb push_back#define mk make_pair#define Mid (tr[u].l+tr[u].r>>1)#define Len(u) (tr[u].r-tr[u].l+1)#define random(a,b) ((a)+rand()%((b)-(a)+1))#define db puts("---")using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;typedef unsigned long long ULL;typedef pair
PII;const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f;const double eps=1e-6;int n,m;int root[N],tot,idx;int dfn[N],se[N],depth[N];vector
v[N];struct Node{ int l,r; LL sum;}tr[N*40];void insert(int p,int &q,int l,int r,int pos,int x){ q=++tot; tr[q]=tr[p]; tr[q].sum+=x; if(l==r) return; int mid=l+r>>1; if(pos<=mid) insert(tr[p].l,tr[q].l,l,mid,pos,x); else insert(tr[p].r,tr[q].r,mid+1,r,pos,x);}LL query(int p,int q,int l,int r,int ql,int qr){ if(l>=ql&&r<=qr) return tr[q].sum-tr[p].sum; LL ans=0; int mid=l+r>>1; if(ql<=mid) ans+=query(tr[p].l,tr[q].l,l,mid,ql,qr); if(qr>mid) ans+=query(tr[p].r,tr[q].r,mid+1,r,ql,qr); return ans;}void dfs1(int u,int fa){ se[u]=1; dfn[u]=++idx; depth[u]=depth[fa]+1; for(auto x:v[u]) if(x!=fa) dfs1(x,u),se[u]+=se[x];}void dfs2(int u,int fa){ insert(root[dfn[u]-1],root[dfn[u]],1,n,depth[u],se[u]-1); for(auto x:v[u]) if(x!=fa) dfs2(x,u);}int main(){ // ios::sync_with_stdio(false);// cin.tie(0); scanf("%d%d",&n,&m); for(int i=1;i<=n-1;i++) { int a,b; scanf("%d%d",&a,&b); v[a].pb(b); v[b].pb(a); } dfs1(1,0); dfs2(1,0); while(m--) { int p,k; scanf("%d%d",&p,&k); LL ans=1ll*min(depth[p]-1,k)*(se[p]-1); ans+=query(root[dfn[p]],root[dfn[p]+se[p]-1],1,n,depth[p]+1,min(depth[p]+k,n)); printf("%lld\n",ans); } return 0;}/**/

转载地址:http://xvlx.baihongyu.com/

你可能感兴趣的文章
mysql slave 停了_slave 停止。求解决方法
查看>>
MySQL SQL 优化指南:主键、ORDER BY、GROUP BY 和 UPDATE 优化详解
查看>>
MYSQL sql语句针对数据记录时间范围查询的效率对比
查看>>
mysql sum 没返回,如果没有找到任何值,我如何在MySQL中获得SUM函数以返回'0'?
查看>>
mysql Timestamp时间隔了8小时
查看>>
Mysql tinyint(1)与tinyint(4)的区别
查看>>
mysql union orderby 无效
查看>>
mysql v$session_Oracle 进程查看v$session
查看>>
mysql where中如何判断不为空
查看>>
MySQL Workbench 使用手册:从入门到精通
查看>>
mysql workbench6.3.5_MySQL Workbench
查看>>
MySQL Workbench安装教程以及菜单汉化
查看>>
MySQL Xtrabackup 安装、备份、恢复
查看>>
mysql [Err] 1436 - Thread stack overrun: 129464 bytes used of a 286720 byte stack, and 160000 bytes
查看>>
MySQL _ MySQL常用操作
查看>>
MySQL – 导出数据成csv
查看>>
MySQL —— 在CentOS9下安装MySQL
查看>>
MySQL —— 视图
查看>>
mysql 不区分大小写
查看>>
mysql 两列互转
查看>>