题目背景

感谢hzwer的点分治互测。

题目描述

给定一棵有n个点的树

询问树上距离为k的点对是否存在。

输入输出格式

输入格式:

n,m 接下来n-1条边a,b,c描述a到b有一条长度为c的路径

接下来m行每行询问一个K

输出格式:

对于每个K每行输出一个答案,存在输出“AYE”,否则输出”NAY”(不包含引号)

输入输出样例

输入样例#1:

2 1
1 2 2
2
输出样例#1:

AYE

说明

对于30%的数据n<=100

对于60%的数据n<=1000,m<=50

对于100%的数据n<=10000,m<=100,c<=1000,K<=10000000


套用点分治的模板。

设num[k]为树中长度为k的路径的出现次数。

对于一个点no,可以dfs遍历一遍以它为根的子树中、以它开头向下的链长度。

对于每一对以no开头的链长度d[i],d[j],num[d[i]+d[j]]++即可。

当然要记得容斥,因为要去掉d[i],d[j]表示的链来自no的同一个儿子。

设no与一个儿子相连边的长度为dis,在递归处理这个儿子的时候,对儿子的每一对d[i],d[j],做num[d[i]+d[j]+dis*2]--即可。

 #include<cstdio>
#include<cstring>
#include<iostream>
#define rint register int
using namespace std; int read(){
char ch;
int re=;
bool flag=;
while((ch=getchar())!='-'&&(ch<''||ch>''));
ch=='-'?flag=:re=ch-'';
while((ch=getchar())>=''&&ch<='') re=re*+ch-'';
return flag?-re:re;
} struct Edge{
int to,nxt,w;
Edge(int to=,int nxt=,int w=):
to(to),nxt(nxt),w(w){}
}; const int maxn=; int n,m,cnt=,sum,tot,root;
int head[maxn],son[maxn],F[maxn],num[],d[maxn];
bool vis[maxn];
Edge E[maxn<<]; inline void a_ed(int from,int to,int w){
E[++cnt]=Edge(to,head[from],w);
head[from]=cnt;
E[++cnt]=Edge(from,head[to],w);
head[to]=cnt;
} void init(){
n=read(); m=read();
for(rint i=,from,to,w;i<n;i++){
from=read(); to=read(); w=read();
a_ed(from,to,w);
}
} void getroot(int no,int fa){
son[no]=; F[no]=;
for(rint e=head[no];e;e=E[e].nxt){
int nt=E[e].to;
if(nt==fa||vis[nt]) continue;
getroot(nt,no);
son[no]+=son[nt];
F[no]=max(F[no],son[nt]);
}
F[no]=max(F[no],sum-son[no]);
if(F[no]<F[root]) root=no;
} void getdeep(int no,int fa,int dd){
d[tot++]=dd;
for(rint e=head[no];e;e=E[e].nxt){
int nt=E[e].to;
if(nt==fa||vis[nt]) continue;
getdeep(nt,no,dd+E[e].w);
}
} void calc(int no,bool opt,int p){
tot=;
getdeep(no,,);
for(int i=;i<tot;i++)
for(int j=;j<tot;j++)
if(opt) num[d[i]+d[j]]++;
else num[d[i]+d[j]+p]--;
} void solve(int no){
vis[no]=;
calc(no,,);
for(rint e=head[no];e;e=E[e].nxt){
int nt=E[e].to;
if(vis[nt]) continue;
calc(nt,,E[e].w<<);
sum=son[nt]; root=;
getroot(nt,);
solve(nt);
}
} int main(){
init();
sum=F[root=]=n;
getroot(,);
solve(root);
for(rint i=,q;i<m;i++){
q=read();
if(num[q]) puts("AYE");
else puts("NAY");
}
return ;
}

luoguP3806 【模板】点分治1 [点分治]的更多相关文章

  1. 【Luogu3806】点分治(点分治)

    [Luogu3806]点分治(点分治) 题面 题目描述 给定一棵有n个点的树 询问树上距离为k的点对是否存在. 输入格式: n,m 接下来n-1条边a,b,c描述a到b有一条长度为c的路径 接下来m行 ...

  2. COGS 2479. [HZOI 2016]偏序 [CDQ分治套CDQ分治 四维偏序]

    传送门 给定一个有n个元素的序列,元素编号为1~n,每个元素有三个属性a,b,c,求序列中满足i<j且ai<aj且bi<bj且ci<cj的数对(i,j)的个数. 对于100%的 ...

  3. 洛谷P4721 【模板】分治 FFT(分治FFT)

    传送门 多项式求逆的解法看这里 我们考虑用分治 假设现在已经求出了$[l,mid]$的答案,要计算他们对$[mid+1,r]$的答案的影响 那么对右边部分的点$f_x$的影响就是$f_x+=\sum_ ...

  4. [模板] 多项式: 乘法/求逆/分治fft/微积分/ln/exp/幂

    多项式 代码 const int nsz=(int)4e5+50; const ll nmod=998244353,g=3,ginv=332748118ll; //basic math ll qp(l ...

  5. 点分治&&动态点分治学习笔记

    突然发现网上关于点分和动态点分的教程好像很少……蒟蒻开篇blog记录一下吧……因为这是个大傻逼,可能有很多地方写错,欢迎在下面提出 参考文献:https://www.cnblogs.com/LadyL ...

  6. 「分治」-cdq分治

    cdq分治是一种分治算法: 一种分治思想,必须离线,可以用来处理序列上的问题(比如偏序问题),还可以优化1D/1D类型的DP.• 算法的大体思路我们可以用点对来描述.假定我们有一个长度为n的序列,要处 ...

  7. hdu 5126 stars cdq分治套cdq分治+树状数组

    题目链接 给n个操作, 第一种是在x, y, z这个点+1. 第二种询问(x1, y1, z1). (x2, y2, z2)之间的总值. 用一次cdq分治可以将三维变两维, 两次的话就变成一维了, 然 ...

  8. 点分治&动态点分治小结

    (写篇博客证明自己还活着×2) 转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/8006488.html 有的时候,我们会发现这样一类题:它长得很像一个$O(n) ...

  9. poj2114 树分治(点分治)

    poj1741板子套一套,统计对数的方式改一下,可以在O(n)时间内统计对数 最后不要忘记输出最后的“.” /* 给定一棵边权树,是否存在一条路径使得其长度为恰好为x 把1741的板子改为求点对之间的 ...

随机推荐

  1. java基础学习笔记五(抽象类)

    java基础学习总结——抽象类 抽象类介绍

  2. Mysql 列变行其中一种做法。

    需求是: 上班打卡记录   和  下班打卡记录  是分别是两条数据,现在是要合并为一条数据,并且封装成一个实体. 有可能是 只有上班记录,,或者是只有下班的记录.如何关联全查,一边为null或者另一边 ...

  3. 洛谷P1364 医院设置(Floyd)

    题目描述 设有一棵二叉树,如图: 其中,圈中的数字表示结点中居民的人口.圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为l.如上 ...

  4. null-ouc 小组冲刺阶段博客目录

    null-ouc Beta冲刺阶段博客目录 github:https://github.com/orgs/OUC-null/people  一.Scrum Meeting 1. [第十周会议记录](h ...

  5. Angular项目中迭代生成的树,激活选中的节点,并将节点数据发送到父节点

    从后台返回的数据,还有多层子节点,需要一个生成树的组件,如果直接在页面上写循环来拼接感觉会很麻烦,因为数据的层级结构不固定. 参考网上其他人的方法,整理如下: 1. 创建一个用于循环迭代的组件,在父组 ...

  6. linux基础知识汇总(三)-vmware下ubuntu上网配置

    方式1 : 使用NAT共享IP的方式.使用这种方式什么都不用设置就可以在ubuntu中上网冲浪了. 备注: 1.如果ubuntu还不能上网的话,可以到我们的电脑的“服务”里面,检查“VMware NA ...

  7. 一起探讨下POST、GET请求

    以下的讨论都是基于java和Spring MVC,主要记录自己的一些练习心得. 做web网站开发HTTP请求必不可少,一直在使用写好的Utils没有考虑过如何以及为什么,现在闲下来想着捋一捋java的 ...

  8. MySQL 5.7配置文件

    原文:http://www.voidcn.com/article/p-zrikccdi-hr.html # MySql5.7配置文件my.cnf设置[client]port = 3306socket ...

  9. php打包下载文件

    使用前请先开启:查看下php.ini里面的extension=php_zip.dll前面的分号有没有去掉; $zip=new \ZipArchive(); $zifile = 'download/' ...

  10. 导数与偏导数 Derivative and Partial Derivative

    之前做了很长时间“罗辑思维”的听众,罗胖子曾经讲起过,我们这一代人该如何学习.其中,就讲到我们这个岁数,已经不可能再去从头到尾的学习一门又一门工具课程了,而是在学习某一领域时,有目的的去翻阅工具课程中 ...