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 ...
随机推荐
- 机器学习(二十四)— 偏差Bias 与方差Variance
1.首先 Error = Bias + Variance Error反映的是整个模型的准确度, Bias反映的是模型在样本上的输出与真实值之间的误差,即模型本身的精准度, Variance反映的是模 ...
- qt和makefile学习网址
http://blog.51cto.com/zt/20/1/ ---qt学习网站 http://www.chinaunix.net/old_jh/23/408225.html [精华] 跟我一起 ...
- Python基础-操作mysql
mysql 属于第三方模块,需要先安装 pip install pymysql,sql执行后,数据获取函数有三种cur.fetchone()#获取第一条数据,依次类推下去,第二次执行时候,就会取除去第 ...
- 《Effective C++》学习笔记(一)
1.const成员函数不能更改成员变量 #include <bits/stdc++.h> using namespace std; class CtextBlock { public: s ...
- SSH Secure Shell 的使用
一,安装Secure Shell ,之后会出现SSH Secure Shell client 和SSH Secure File Transfer client 两个快捷方式. 需要服务器的IP地址,用 ...
- Python 标准库 —— 邮件(email)与邮件服务器(smtplib)
你真的懂邮件吗?邮件包括如下四部分内容: 发送人:from_addr 接收人:to_addr 主题:subject 正文:msg(mime text 格式文本) 其中发送者,接收者,又需要两部分的内容 ...
- msdtc中rpc调试
http://www.cnblogs.com/nzperfect/archive/2011/11/03/2234595.html 1 工具: dtcping 2 配置 3 netboise
- ACM学习历程—BZOJ2956 模积和(数论)
Description 求∑∑((n mod i)*(m mod j))其中1<=i<=n,1<=j<=m,i≠j. Input 第一行两个数n,m. Output 一个整数表 ...
- 【Google】循环字符串里面的独立子串
转载自九章算法(地址) 题目: 假设s是一个无限循环的字符串”abcdefghijklmnopqrstuvwxyz”,s就是一个”...zabcdefghijklmnopqrstuvwxyza...” ...
- BZOJ4003:[JLOI2015]城池攻占
浅谈左偏树:https://www.cnblogs.com/AKMer/p/10246635.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php? ...