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. 阿里云服务器Linux系统安装配置ElasticSearch搜索引擎

    近几篇ElasticSearch系列: 1.阿里云服务器Linux系统安装配置ElasticSearch搜索引擎 2.Linux系统中ElasticSearch搜索引擎安装配置Head插件 3.Ela ...

  2. MySQL☞substr函数

    substr函数:截取字符串 格式如下: select  substr(参数1,参数2,参数3)  from  表名 参数1:列名/字符串 参数2:起始位置,如果为正数,就表示从正数的位置往下截取字符 ...

  3. Python元组与列表的区别和联系?

    1.  元组和列表比较相似,不过它们之间也有着不同: (1)列表:一个大仓库,你可以随时往里边添加和删除任何东西. (2)元组:封闭的列表,一旦定义,就不可改变(不能添加.删除或修改). 2. 什么情 ...

  4. 《Git学习指南》学习笔记(一)

    第二章 入门 git的安装 在Linux下,git的安装很简单.以我的系统Deepin/Ubuntu为例,只需在终端敲入sudo apt-get install git即可.其他Linux发行版可尝试 ...

  5. Bootstrap框架(图标)

    Glyphicons 字体图标 所有可用的图标 包括250多个来自 Glyphicon Halflings 的字体图标.Glyphicons Halflings 一般是收费的,但是他们的作者允许 Bo ...

  6. 【转】使用CNPM搭建私有NPM

    最近的Node项目中因为数据模型等问题,需要有一个对各个模块进行统一的管理,如果把私有的模型publish到公共的npm不太合适,所以决定使用cnpm搭建一个私有的npm,同时也可以对项目常用的npm ...

  7. 关于localStorage的实际应用

    在客户端存储数据 HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 之前, ...

  8. 第二十一次ScrumMeeting会议

    第二十一次Scrum Meeting 时间:2017/12/11 地点:SPR咖啡馆 人员:王子铭 游心 解小锐 王辰昱 李金奇 杨森 陈鑫 赵晓宇 照片: 目前工作进展 名字 今日 明天的工作 蔡帜 ...

  9. ACM 第一天

    标签库元素: 队列<queue> FIFO 栈 <stack>  FICO 集合 set 不定长数组  vector 映射 map Maximum Multiple Time ...

  10. 解决打包遇到的_mssql问题

    明明上一篇还说着打包好了,这一个又出现了问题,真是让人揪心呀!错误如下: Traceback (most recent call last): File "macc.py", li ...