luoguP3806 【模板】点分治1 [点分治]
题目背景
感谢hzwer的点分治互测。
题目描述
给定一棵有n个点的树
询问树上距离为k的点对是否存在。
输入输出格式
输入格式:
n,m 接下来n-1条边a,b,c描述a到b有一条长度为c的路径
接下来m行每行询问一个K
输出格式:
对于每个K每行输出一个答案,存在输出“AYE”,否则输出”NAY”(不包含引号)
输入输出样例
2 1
1 2 2
2
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 [点分治]的更多相关文章
- 【Luogu3806】点分治(点分治)
[Luogu3806]点分治(点分治) 题面 题目描述 给定一棵有n个点的树 询问树上距离为k的点对是否存在. 输入格式: n,m 接下来n-1条边a,b,c描述a到b有一条长度为c的路径 接下来m行 ...
- COGS 2479. [HZOI 2016]偏序 [CDQ分治套CDQ分治 四维偏序]
传送门 给定一个有n个元素的序列,元素编号为1~n,每个元素有三个属性a,b,c,求序列中满足i<j且ai<aj且bi<bj且ci<cj的数对(i,j)的个数. 对于100%的 ...
- 洛谷P4721 【模板】分治 FFT(分治FFT)
传送门 多项式求逆的解法看这里 我们考虑用分治 假设现在已经求出了$[l,mid]$的答案,要计算他们对$[mid+1,r]$的答案的影响 那么对右边部分的点$f_x$的影响就是$f_x+=\sum_ ...
- [模板] 多项式: 乘法/求逆/分治fft/微积分/ln/exp/幂
多项式 代码 const int nsz=(int)4e5+50; const ll nmod=998244353,g=3,ginv=332748118ll; //basic math ll qp(l ...
- 点分治&&动态点分治学习笔记
突然发现网上关于点分和动态点分的教程好像很少……蒟蒻开篇blog记录一下吧……因为这是个大傻逼,可能有很多地方写错,欢迎在下面提出 参考文献:https://www.cnblogs.com/LadyL ...
- 「分治」-cdq分治
cdq分治是一种分治算法: 一种分治思想,必须离线,可以用来处理序列上的问题(比如偏序问题),还可以优化1D/1D类型的DP.• 算法的大体思路我们可以用点对来描述.假定我们有一个长度为n的序列,要处 ...
- hdu 5126 stars cdq分治套cdq分治+树状数组
题目链接 给n个操作, 第一种是在x, y, z这个点+1. 第二种询问(x1, y1, z1). (x2, y2, z2)之间的总值. 用一次cdq分治可以将三维变两维, 两次的话就变成一维了, 然 ...
- 点分治&动态点分治小结
(写篇博客证明自己还活着×2) 转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/8006488.html 有的时候,我们会发现这样一类题:它长得很像一个$O(n) ...
- poj2114 树分治(点分治)
poj1741板子套一套,统计对数的方式改一下,可以在O(n)时间内统计对数 最后不要忘记输出最后的“.” /* 给定一棵边权树,是否存在一条路径使得其长度为恰好为x 把1741的板子改为求点对之间的 ...
随机推荐
- InnoDB事务之redo log工作原理
Reference:https://time.geekbang.org/column/article/121710 InnoDB是一个事务性的存储引擎,而InnoDB的事务实现是基于事务日志redo ...
- 【leetcode】908. Smallest Range I
题目如下: 解题思路:简单的不能再简单的题目了,对于任意一个A[i]来说,其可能的最小的最大值是A[i]-K,最大的最小值是A[i]+K.遍历数组,求出所有元素中最大的最小值和最小的最大值,两者之差( ...
- Vue.js(七)
ES6 默认导出(只能一次)与默认导入 默认导出: // 当前文件模块为 test.js // 定义私有成员 a 和 c let a = 10 let c = 20 // 外界访问不到变量 d ,因为 ...
- 工厂方法配置bean
1:静态工厂方法配置bean 1):对象 package com.spring.helloworld; public class Car { private String name; private ...
- pic16f877a的PWM实验学习
遇到的问题,编译时找不到TRISC.一开始以为头文件中没有定义,发现定义了. 所以是自己创建工程的时候,设备类型选错了. #include <pic.h> __CONFIG(0xFF32) ...
- PCB一些设置记录
开始时设置原点,编辑>>原点>>设置 画PCB时,导入后,根据各个模块放好位置 设计>>类>>添加电源类 设计>>规则>>Cle ...
- TextView详解
android:autoLink设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接.可选值(none/web /email/phone/map/all)android: ...
- PostgreSQL的约束
约束类型:检查约束.非空约束.唯一约束.主键.外键 1. 检查约束 设置某个字段里的数值必须满足约束表达式的条件. 例:限制人的年龄在0~120之间,语句如下: create table perso ...
- 如何查看red gate安装时的log
安装界面,点击左上角的log open log file C:\Users\clu\AppData\Local\Temp\{69EEB6B0-A9AD-4BD4-8231-92C992F1FF05}\ ...
- MySQL concat、concat_ws 和 group_concat 的用法
一.CONCAT()函数CONCAT()函数用于将多个字符串连接成一个字符串.使用数据表Info作为示例,其中SELECT id,name FROM info LIMIT 1;的返回结果为+----+ ...