description

求树上长度为\(k\)的路径是否存在。

data range

\[n\le 10000,k\le 10000000
\]

solution

点分治复习。。。

使用普通的点分治枚举路径模板即可。

一个小细节

本人初学点分治的时候是这样写的

int sum,rt,sz[N],w[N];bool vis[N];
void getrt(int u,int ff){//找到对应连通块的重心
sz[u]=1;w[u]=0;
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(v==ff||vis[v])continue;
getrt(v,u);sz[u]+=sz[v];
w[u]=max(w[u],sz[v]);
}
w[u]=max(w[u],blk-sz[u]);
if(w[rt]>w[u])rt=u;
}
void solve(int u){//递归分治
vis[u]=1;
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(vis[v])continue;
rt=0;blk=sz[v];
getrt(v,0);
solve(rt);
}
} int main()
{
//...
rt=0;w[0]=sum=n;
getrt(1,0);
solve(rt);
return 0;
}

现在感觉这样写有问题。

关键出在直接赋值\(sum=sz[v]\)上。

给出一棵树:



我们第一次选择的重心是节点\(3\)

然而这时\(sz[1]=6\)

于是我们递归解决上面部分的时候重心就会受到影响

然后就可能会\(T\)

解决方法是两边\(dfs\)像这样似乎常数又加大了:

int sum,rt,sz[N],w[N];bool vis[N];
void getrt(int u,int ff){//找到对应连通块的重心
sz[u]=1;w[u]=0;
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(v==ff||vis[v])continue;
getrt(v,u);sz[u]+=sz[v];
w[u]=max(w[u],sz[v]);
}
w[u]=max(w[u],blk-sz[u]);
if(w[rt]>w[u])rt=u;
}
void solve(int u){//递归分治
vis[u]=1;
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(vis[v])continue;
rt=0;blk=sz[v];
getrt(v,0);
getrt(rt,0);//第二遍dfs
solve(rt);
}
} int main()
{
//...
rt=0;w[0]=sum=n;
getrt(1,0);
getrt(rt,0);//第二遍dfs
solve(rt);
return 0;
}

Code

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define Cpy(x,y) memcpy(x,y,sizeof(x))
#define Set(x,y) memset(x,y,sizeof(x))
#define FILE "a"
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const int N=10010;
const int M=10000010;
const dd eps=1e-5;
const int inf=2147483647;
const ll INF=1ll<<60;
const ll P=100000;
il ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
} il void file(){
srand(time(NULL)+rand());
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
} int n,m,rt,blk,k,flg;
int head[N],nxt[N<<1],to[N<<1],val[N<<1],cnt;
il void add(int u,int v,int w){
to[++cnt]=v;val[cnt]=w;nxt[cnt]=head[u];head[u]=cnt;
} int sz[N],w[N];bool vis[N],tong[M];
void getrt(int u,int ff){
sz[u]=1;w[u]=0;
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(v==ff||vis[v])continue;
getrt(v,u);sz[u]+=sz[v];
w[u]=max(w[u],sz[v]);
}
w[u]=max(w[u],blk-sz[u]);
if(w[rt]>w[u])rt=u;
} int dep[N],cal[N],top;
void getdep(int u,int ff){
cal[++top]=dep[u];
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(v==ff||vis[v])continue;
dep[v]=dep[u]+val[i];if(dep[v]<=k)getdep(v,u);
}
}
void getcl(int u,int ff){
tong[dep[u]]=0;
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(v==ff||vis[v])continue;
getcl(v,u);
}
}
void solve(int u){
vis[u]=1;dep[u]=0;cal[++top]=0;
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(vis[v])continue;
dep[v]=dep[u]+val[i];getdep(v,u);
for(RG int j=1;j<=top;j++)
if(tong[k-cal[j]]||cal[j]==k)flg=1;
for(RG int j=1;j<=top;j++)
tong[cal[j]]=1;
top=0;
}
getcl(u,0);
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(vis[v])continue;
rt=0;blk=sz[v];
getrt(v,0);
getrt(rt,0);
solve(rt);
}
} int main()
{
n=read();m=read();
for(RG int i=1,u,v,w;i<n;i++){
u=read();v=read();w=read();
add(u,v,w);add(v,u,w);
}
for(RG int i=1;i<=m;i++){
k=read();flg=0;
memset(vis,0,sizeof(vis));
rt=0;blk=w[0]=n;
getrt(1,0);
getrt(rt,0);
solve(rt); flg?puts("AYE"):puts("NAY");
}
return 0;
}

[luogu3806]【模板】点分治1的更多相关文章

  1. 【Luogu3806】点分治(点分治)

    [Luogu3806]点分治(点分治) 题面 题目描述 给定一棵有n个点的树 询问树上距离为k的点对是否存在. 输入格式: n,m 接下来n-1条边a,b,c描述a到b有一条长度为c的路径 接下来m行 ...

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

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

  3. luoguP4721 【模板】分治 FFT

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

  4. LG4721 【模板】分治 FFT

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

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

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

  6. 【洛谷4721】【模板】分治FFT(CDQ分治_NTT)

    题目: 洛谷 4721 分析: 我觉得这个 "分治 FFT " 不能算一种特殊的 FFT ,只是 CDQ 分治里套了个用 FFT (或 NTT)计算的过程,二者是并列关系而不是偏正 ...

  7. [模板] CDQ分治&&BZOJ3262:陌上花开

    简介 CDQ分治是分治的一种, 可以看做归并排序的扩展, 利用离线将一些 \(O(n)\) 的暴力优化到 \(O(log n)\). 它可以用来顶替一些高级(log)数据结构等. 一般地, CDQ分治 ...

  8. P4721【模板】分治 FFT

    瞎扯 虽然说是FFT但是还是写了一发NTT(笑) 然后忘了IDFT之后要除个n懵逼了好久 以及递归的时候忘了边界无限RE 思路 朴素算法 分治FFT 考虑到题目要求求这样的一个式子 \[ F_x=\S ...

  9. P4721 【模板】分治 FFT

    其实是分治ntt,因为fft会爆精度,真*裸题 分治过程和fft的一模一样,主要就是ntt精度高,用原根来代替fft中的\(w_n^k\) 1.定义:设m>1,(a,m)==1,满足\(a^r= ...

  10. [洛谷P4721]【模板】分治 FFT_求逆

    题目大意:给定长度为$n-1$的数组$g_{[1,n)}$,求$f_{[0,n)}$,要求: $$f_i=\sum_{j=1}^if_{i-j}g_j\\f_0=1$$ 题解:分治$FFT$博客,发现 ...

随机推荐

  1. Servlet处理文件下载的编码问题,乱码。

    Servlet处理文件下载的编码问题,乱码. //处理文件名乱码问题 // 获得请求头中的User-Agent String agent = request.getHeader("User- ...

  2. 使用conlleval.pl对CRF测试结果进行评价的方法

    基于CRF做命名实体识别系列 用CRF做命名实体识别(一) 用CRF做命名实体识别(二) 用CRF做命名实体识别(三) 评测 用CRF做完命名实体识别我们测试之后得到的结果就是预测的标签,并不能直接得 ...

  3. python爬取视频网站m3u8视频,下载.ts后缀文件,合并成整视频

    最近发现一些网站,可以解析各大视频网站的vip.仔细想了想,这也算是爬虫呀,爬的是视频数据. 首先选取一个视频网站,我选的是 影视大全 ,然后选择上映不久的电影 “一出好戏” . 分析页面 我用的是c ...

  4. 测试开发的成长之路 - 自动化一站式平台(UI、接口)

    前言 在自动化测试过程中,随着对接的自动化需求不断增加,测试用例数量显著上升,参与自动化测试的人也越来越多,多人协作就会碰到很多问题,包括脚本.数据.版本.项目整合.持续集成等,而且也增加了后期维护的 ...

  5. Python简要标准库(1)

    sys sys这个模块让你能够访问与Python解释器联系紧密的变量和函数 其中的一些在下表 F argv 命令行参数,包括脚本名称 exit([arg]) 退出当前的程序,可选参数为给定的返回值或者 ...

  6. 在使用Pipeline串联多个stage时model和非model的区别

    train.csv数据: id,name,age,sex1,lyy,20,F2,rdd,20,M3,nyc,18,M4,mzy,10,M 数据读取: SparkSession spark = Spar ...

  7. Java Web开发框架Spring+Hibernate整合效果介绍(附源码)(已过期,有更好的)

    最近花了一些时间整合了一个SpringMVC+springAOP+spring security+Hibernate的一套框架,之前只专注于.NET的软件架构设计,并没有接触过Java EE,好在有经 ...

  8. HTMLTestRunner带饼图

    # -*- coding: utf-8 -*- """ A TestRunner for use with the Python unit testing framewo ...

  9. java length属性、length()、size()

    length属性 length是属性,用于说明数组的长度. String []list={"wo","shi","shuaibi"}; Sy ...

  10. LeetCode 109——有序链表转化二叉搜索树

    1. 题目 2. 解答 2.1. 方法一 在 LeetCode 108--将有序数组转化为二叉搜索树 中,我们已经实现了将有序数组转化为二叉搜索树.因此,这里,我们可以先遍历一遍链表,将节点的数据存入 ...