题目背景

感谢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. 前端解析Markdown

    目录 前端解析Markdown 1.使用strapdown 1.1.下载 1.2.使用 2.使用marked(配合highlightjs) 2.1.下载 2.2.使用 3.使用mdjs(配合highl ...

  2. Reverse array

    数组颠倒算法 #include <iostream> #include <iterator> using namespace std; void reverse(int* A, ...

  3. nucleus学习

    task的TCB结构: typedef struct TC_TCB_STRUCT { /* Standard thread information first. This information is ...

  4. getcwd函数学习

    getcwd 函数原型:char *getcwd( char *buffer, int maxlen ); 功 能:获取当前工作目录 参数说明:getcwd()会将当前工作目录的绝对路径复制到参数bu ...

  5. Android的Context && 安卓常用系统服务(当前运行包名/当前网络状态和开关网络/音频服务/马达服务) (转)

    转:http://blog.csdn.net/zhandoushi1982/article/details/8501773 Context字面意思上下文,位于framework 的android.co ...

  6. PHP面试 MySQL创建高性能索引考点

    MySQL索引 MySQL索引的基础和类型 索引的基础:索引类似于书籍的目录,要想找到一本书的某个特定篇章,需要查找书的目录,定位对应的页码 存储引擎使用类似的方式进行数据查询,先去索引当中找到对应的 ...

  7. 图片模式CMYK和RGB在浏览器下的变化

    手机浏览器里面不能显示出模式为CMYK的图片, 模式为CMYK的图片在IE浏览器里面显示和模式为RGB的一样 模式为CMYK的图片在火狐里面显示有色差

  8. camunda用户的一些简单操作

    act_id_group:存放组信息act_id_membership:存放用户与组的相关信息act_id_user:存放用户act_id_info:存放用户个人信息act_id_tenant:存放租 ...

  9. JavaFX教程

    JavaFX是Java的下一代图形用户界面工具包.JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序. JavaFX允许开发人员快速构建丰富的跨平台应用程序.JavaFX通 ...

  10. Visual Studio 2013创建并运行Cocos2d-x工程

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 1.准备: 我们得先把Visual Studio 2013安装好:可以去MSDN官网下载,在安装好 2.安装好vs之后,在cmd(终端)创 ...