luogu 3806 【模板】点分治
luogu 3806 【模板】点分治
给定一棵有n个点的树,有m个询问,每个询问树上距离为k的点对是否存在。树的权值最多不超过c。n<=10000,m<=100,c<=1000,K<=10000000。
关于树的路径的问题,点分治是一种最吼的工具。由于这道题的m比较小,枚举k,通过set保存每颗子树中点的路径值,在set中查询每个k值是否成立即可。似乎空间消耗很小,只用了2.3mb。
#include <set>
#include <cctype>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1e4+5;
struct Graph{
struct Edge{
int to, next, v; Graph *bel;
Edge& operator ++(){
return *this=bel->edge[next]; }
}edge[maxn*2];
int cnte, fir[maxn];
void addedge(int x, int y, int v){
Edge &e=edge[++cnte];
e.to=y; e.next=fir[x]; e.v=v;
fir[x]=cnte; e.bel=this;
}
Edge& getlink(int x){ return edge[fir[x]]; }
void RESET(){
cnte=0; memset(fir, 0, sizeof(fir)); }
}g;
int n, m, k[maxn], size[maxn], f[maxn];
int dep[maxn], tail;
set<int> s;
bool done[maxn], hasans[maxn];
//获取子树大小和最大子树大小
void predfs(int now, int par, int num){
Graph::Edge e=g.getlink(now);
size[now]=1; f[now]=0;
for (; e.to; ++e){
if (e.to==par||done[e.to]) continue;
predfs(e.to, now, num);
size[now]+=size[e.to];
f[now]=max(f[now], size[e.to]);
}
f[now]=max(f[now], num-size[now]);
}
//找到根
int getroot(int now, int par){
Graph::Edge e=g.getlink(now);
int core=now, t;
for (; e.to; ++e){
if (e.to==par||done[e.to]) continue;
t=getroot(e.to, now);
if (f[t]<f[core]) core=t;
}
return core;
}
//获取到所有点的深度
void getdep(int now, int par, int step){
Graph::Edge e=g.getlink(now);
for (; e.to; ++e) if (e.to!=par&&!done[e.to])
getdep(e.to, now, step+e.v);
dep[++tail]=step;
for (int i=1; i<=m; ++i)
if (s.find(k[i]-dep[tail])!=s.end())
hasans[i]=true;
}
void solve(int now, int par, int num){
predfs(now, 0, num); //预处理
if (size[now]==1) return;
now=getroot(now, 0); //找出重心
predfs(now, 0, num);
s.clear(); s.insert(0);
Graph::Edge e=g.getlink(now);
for (; e.to; ++e){
if (e.to==par||done[e.to]) continue;
tail=0;
getdep(e.to, now, e.v); //找出所有点的深度
for (int i=1; i<=tail; ++i)
s.insert(dep[i]);
}
//不能统计带有回头路的
e=g.getlink(now);
done[now]=true;
for (; e.to; ++e) if (e.to!=par&&!done[e.to])
solve(e.to, now, size[e.to]); //找子树
}
void get(int &x){
x=0; int flag=1; char c;
for (c=getchar(); !isdigit(c); c=getchar())
if (c=='-') flag=-flag;
for (x=c-48; c=getchar(), isdigit(c); )
x=(x<<3)+(x<<1)+c-48; x*=flag;
}
int main(){
get(n); get(m);
int t1, t2, t3;
for (int i=1; i<n; ++i){
get(t1); get(t2); get(t3);
g.addedge(t1, t2, t3);
g.addedge(t2, t1, t3);
}
for (int i=1; i<=m; ++i) get(k[i]);
solve(1, 0, n);
for (int i=1; i<=m; ++i) puts(hasans[i]?"AYE":"NAY");
return 0;
}
luogu 3806 【模板】点分治的更多相关文章
- Luogu 3806 点分治1
Luogu 3806 点分治 要分清楚各个函数的作用及互相调用的关系. 因为是无根树,找重心的时候,父亲一边的所有节点也可以看做是一颗子树. #include<bits/stdc++.h> ...
- luoguP4721 【模板】分治 FFT
P4721 [模板]分治 FFT 链接 luogu 题目描述 给定长度为 \(n-1\) 的数组 \(g[1],g[2],..,g[n-1]\),求 \(f[0],f[1],..,f[n-1]\),其 ...
- [luogu P3384] [模板]树链剖分
[luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点 ...
- 洛谷 P4721 【模板】分治 FFT 解题报告
P4721 [模板]分治 FFT 题目背景 也可用多项式求逆解决. 题目描述 给定长度为 \(n−1\) 的数组 \(g[1],g[2],\dots,g[n-1]\),求 \(f[0],f[1],\d ...
- Luogu P2742 模板-二维凸包
Luogu P2742 模板-二维凸包 之前写的实在是太蠢了.于是重新写了一个. 用 \(Graham\) 算法求凸包. 注意两个向量 \(a\times b>0\) 的意义是 \(b\) 在 ...
- LG4721 【模板】分治 FFT
P4721 [模板]分治 FFT 题目背景 也可用多项式求逆解决. 题目描述 给定长度为 $n-1$ 的数组 $g[1],g[2],..,g[n-1]$,求 $f[0],f[1],..,f[n-1]$ ...
- luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)
luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目 #include<iostream> #include<cstdlib> #include< ...
- 模板·点分治(luogu P3806)
[模板]洛谷·点分治 1.求树的重心 树的重心:若A点的子树中最大的子树的size[] 最小时,A为该树的中心 步骤: 所需变量:siz[x] 表示 x 的子树大小(含自己),msz[x] 表示 其子 ...
- Luogu 4721 【模板】分治 FFT
还不会这题的多项式求逆的算法. 发现每一项都是一个卷积的形式,那么我们可以使用$NTT$来加速,直接做是$O(n^2logn)$的,我们考虑如何加速转移. 可以采用$cdq$分治的思想,对于区间$[l ...
随机推荐
- Linux配置redis服务器
1.安装redis 2.开启6379端口,使外部机器能够访问 3.
- Mysql5.5 InnoDB存储引擎配置和优化
环境为CentOS系统,1G内存,Mysql5.5.30.在/etc/my.cnf内添加: 复制代码代码如下: skip-external-lockingskip-name-resolvemax_co ...
- 关于ATML信号定义的理解-1
1.XML中的类型标签: <xs:complexType>复合类型和<xs:simpleTyle>简单类型是数据结构类型,包含了各种类型的属性.可以被子类型继承,继承方式为&l ...
- python字符串相关操作
字符串搜索相关搜索指定字符串,没有返回-1:str.find('t')指定起始位置搜索:str.find('t',start)指定起始及结束位置搜索:str.find('t',start,end)从右 ...
- linux 故障:df -h统计磁盘空间占用太多,但又du -h找不到大的文件
用lsof / | grep -i delete 从根目录定位打开的被删除的文件 如果定位到某文件占用空间很大 主要是因为我们在删除这个日志文件的时候是用rm -rf *.log这样的命令删除的,删除 ...
- 点分治Day1
树套树Day2暂且搁置...因为Day1的题我各种不会做... 唯一过了一道还是整体二分过的... 我们来一点愉快的算法,先不考虑数据结构这种骚东西了 毕竟还在发烧,就先码码这几天在搞的点分治吧 hx ...
- ACM学习历程—HDU5422 Rikka with Graph(贪心)
Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...
- 办公软件-Excel:Microsoft Office Excel 2003百科
ylbtech-办公软件-Excel:Microsoft Office Excel 2003百科 Microsoft® Office Excel 2003 是一种电子表格程序,可提供对于 XML 的支 ...
- UML核心元素--包
包是一种容器,如同文件夹一样,将某些信息分类,形成逻辑单元.包可以容纳任何UML元素,例如用例.业务实体.类图等,也包括子包. 一.分包原则: (1)高内聚:被分入同一个包的元素相互联系紧密,伸至不可 ...
- hibernate 数据关联一对一
第一种一对一 person和card,card的id即作为主键,又作为外键 // 各村对方的一个对象 public class Person { private Integer id; privat ...