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 【模板】点分治的更多相关文章

  1. Luogu 3806 点分治1

    Luogu 3806 点分治 要分清楚各个函数的作用及互相调用的关系. 因为是无根树,找重心的时候,父亲一边的所有节点也可以看做是一颗子树. #include<bits/stdc++.h> ...

  2. luoguP4721 【模板】分治 FFT

    P4721 [模板]分治 FFT 链接 luogu 题目描述 给定长度为 \(n-1\) 的数组 \(g[1],g[2],..,g[n-1]\),求 \(f[0],f[1],..,f[n-1]\),其 ...

  3. [luogu P3384] [模板]树链剖分

    [luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点 ...

  4. 洛谷 P4721 【模板】分治 FFT 解题报告

    P4721 [模板]分治 FFT 题目背景 也可用多项式求逆解决. 题目描述 给定长度为 \(n−1\) 的数组 \(g[1],g[2],\dots,g[n-1]\),求 \(f[0],f[1],\d ...

  5. Luogu P2742 模板-二维凸包

    Luogu P2742 模板-二维凸包 之前写的实在是太蠢了.于是重新写了一个. 用 \(Graham\) 算法求凸包. 注意两个向量 \(a\times b>0\) 的意义是 \(b\) 在 ...

  6. LG4721 【模板】分治 FFT

    P4721 [模板]分治 FFT 题目背景 也可用多项式求逆解决. 题目描述 给定长度为 $n-1$ 的数组 $g[1],g[2],..,g[n-1]$,求 $f[0],f[1],..,f[n-1]$ ...

  7. luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)

    luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目 #include<iostream> #include<cstdlib> #include< ...

  8. 模板·点分治(luogu P3806)

    [模板]洛谷·点分治 1.求树的重心 树的重心:若A点的子树中最大的子树的size[] 最小时,A为该树的中心 步骤: 所需变量:siz[x] 表示 x 的子树大小(含自己),msz[x] 表示 其子 ...

  9. Luogu 4721 【模板】分治 FFT

    还不会这题的多项式求逆的算法. 发现每一项都是一个卷积的形式,那么我们可以使用$NTT$来加速,直接做是$O(n^2logn)$的,我们考虑如何加速转移. 可以采用$cdq$分治的思想,对于区间$[l ...

随机推荐

  1. python MLP 神经网络使用 MinMaxScaler 没有 StandardScaler效果好

    MLP 64,2  preprocessing.MinMaxScaler().fit(X)                               test confusion_matrix:[[ ...

  2. adb命令(一)

    针对移动端 Android 的测试, adb 命令是很重要的一个点,必须将常用的 adb 命令熟记于心, 将会为 Android 测试带来很大的方便,其中很多命令将会用于自动化测试的脚本当中. And ...

  3. Java_异常_05_ OutOfMemoryError: Java heap space

    一.异常现象: 二.异常原因 JAVA的堆栈设置太小 注: 出现此异常之后,会引发其他的问题. 三.异常解决 手动设置Heap size: 修改 TOMCAT_HOME/bin/catalina.sh ...

  4. 5_Singleton 游戏开发中的单例模式

    强制类只有一个实例 提供全局的访问 ###为什么使用: ``` 如果没有地方访问这个类,则不会创建实例 静态类在main之前实例化, 可以尝试Lazy initialization 派生单例类, 获得 ...

  5. User-Agent 及其构造

    url = ... user_agent = ... headers = {'User-Agent' : user_agent} req = requests.request(url=url, hea ...

  6. Ffmpeg转码研究一

    Ffmpeg是一款功能强大的视频处理工具,那么转码肯定不是问题的,因为项目的需求,对转码进行了研究.刚开始首先去看了ffmpeg源代码中的一个例子transcode.c,但是发现该例子更应该称之为re ...

  7. Spring 3.1新特性之四:p命名空间设置注入(待补充)

    https://www.ibm.com/developerworks/cn/java/j-lo-jparelated/ http://www.ibm.com/developerworks/cn/jav ...

  8. netty支持的协议

    流经网络的数据总是具有相同的类型:字节.这些字节是如何流动的主要取决于我们所说的 网络传输--一个帮助我们抽象底层数据传输机制的概念.用户并不关心这些细节:他们只想确保他们的字节被可靠地发送和接收. ...

  9. java中的equals方法

    这个方法首先比较的是两个对象的地址是否相同,如果相同直接返回true, 否则, (1)如果是string类型的先比较是否是string类型,是的话,再比较是否长度相同,相同的话再比较,每个字符是否相同 ...

  10. k8s 基础 问题

    vim /usr/lib/systemd/system/docker.service --insecure-registry registry.access.redhat.com \ ubelet.s ...