Link:

P3806 传送门

Solution:

询问树上是否存在两点间的距离为$k$,共有$m$次询问($m\le 100,k\le 1e7$)

预处理出所有距离的可能性再$O(1)$出解的复杂度为$O(n^2*log(n))$,明显TLE(但好像并不会)

而如果直接在线处理要分治$m$次,找$m$次完全相同的重心,完全没有必要

因此最好采用离线处理的方式

在每个点运用$set$对于每一个$k$查询$k-dist(i)$在之前的子树中是否出现过

预估复杂度和在线其实没什么区别,都为$O(n*m*log(n)^2)$,但少了$m-1$次递归和求重心常数就小了很多

Code:

#include <bits/stdc++.h>

using namespace std;
const int MAXN=;
struct edge{int nxt,to,w;}e[MAXN<<];
set<int> s;
int n,m,x,y,z,st[MAXN],head[MAXN],q[MAXN],res[MAXN],tot,top;
int sz[MAXN],mxsub[MAXN],vis[MAXN],vsum,root; void add_edge(int from,int to,int w)
{
e[++tot].nxt=head[from];e[tot].to=to;e[tot].w=w;head[from]=tot;
e[++tot].nxt=head[to];e[tot].to=from;e[tot].w=w;head[to]=tot;
} void getroot(int x,int anc)
{
sz[x]=;mxsub[x]=;
for(int i=head[x];i;i=e[i].nxt)
{
if(e[i].to==anc||vis[e[i].to]) continue;
getroot(e[i].to,x);sz[x]+=sz[e[i].to];
mxsub[x]=max(mxsub[x],sz[e[i].to]);
}
mxsub[x]=max(mxsub[x],vsum-sz[x]);
if(mxsub[x]<mxsub[root]) root=x;
} void dfs(int x,int anc,int dist)
{
st[++top]=dist;
for(int i=head[x];i;i=e[i].nxt)
{
if(e[i].to==anc||vis[e[i].to]) continue;
dfs(e[i].to,x,dist+e[i].w);
}
} void solve(int x)
{
vis[x]=true;s.clear();s.insert();
for(int i=head[x];i;i=e[i].nxt)
{
if(vis[e[i].to]) continue;
top=;dfs(e[i].to,x,e[i].w);
for(int j=;j<=top;j++)//对m个结果更新
for(int k=;k<=m;k++)
res[k]|=s.count(q[k]-st[j]);
for(int j=;j<=top;j++)
s.insert(st[j]);
}
for(int i=head[x];i;i=e[i].nxt)
{
if(vis[e[i].to]) continue;
vsum=sz[e[i].to];getroot(e[i].to,root=);
solve(root);
}
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
scanf("%d%d%d",&x,&y,&z),add_edge(x,y,z);
for(int i=;i<=m;i++) scanf("%d",&q[i]); vsum=mxsub[]=n;
getroot(,root=);solve(root);
for(int i=;i<=m;i++)
printf(res[i]?"AYE\n":"NAY\n");
return ;
}

Review:

如果点分治问题有多次询问,最好离线

减少递归和求重心的次数

[P3806] Divide and Conquer on Tree的更多相关文章

  1. [LeetCode] 系统刷题4_Binary Tree & Divide and Conquer

    参考[LeetCode] questions conlusion_InOrder, PreOrder, PostOrder traversal 可以对binary tree进行遍历. 此处说明Divi ...

  2. [LeetCode] 124. Binary Tree Maximum Path Sum_ Hard tag: DFS recursive, Divide and conquer

    Given a non-empty binary tree, find the maximum path sum. For this problem, a path is defined as any ...

  3. [LeetCode] 236. Lowest Common Ancestor of a Binary Tree_ Medium tag: DFS, Divide and conquer

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

  4. 算法与数据结构基础 - 分治法(Divide and Conquer)

    分治法基础 分治法(Divide and Conquer)顾名思义,思想核心是将问题拆分为子问题,对子问题求解.最终合并结果,分治法用伪代码表示如下: function f(input x size ...

  5. 【LeetCode】分治法 divide and conquer (共17题)

    链接:https://leetcode.com/tag/divide-and-conquer/ [4]Median of Two Sorted Arrays [23]Merge k Sorted Li ...

  6. 算法上机题目mergesort,priority queue,Quicksort,divide and conquer

    1.Implement exercise 2.3-7. 2. Implement priority queue. 3. Implement Quicksort and answer the follo ...

  7. The Divide and Conquer Approach - 归并排序

    The divide and conquer approach - 归并排序 归并排序所应用的理论思想叫做分治法. 分治法的思想是: 将问题分解为若干个规模较小,并且类似于原问题的子问题, 然后递归( ...

  8. Divide and Conquer.(Merge Sort) by sixleaves

    algo-C1-Introductionhtml, body {overflow-x: initial !important;}html { font-size: 14px; }body { marg ...

  9. [算法]分治算法(Divide and Conquer)

    转载请注明:http://www.cnblogs.com/StartoverX/p/4575744.html 分治算法 在计算机科学中,分治法是建基于多项分支递归的一种很重要的算法范式.字面上的解释是 ...

随机推荐

  1. 【CODEVS】1281 Xn数列

    [算法]矩阵快速幂 [题解]T*A(n-1)=A(n)矩阵如下: a 1 * x(n-1) 0 = xn 0 0 1    c        0    c   0 防止溢出可以用类似快速幂的快速乘. ...

  2. Linux 命令行生成密码的 10 种方式

    内容来自: 10 Ways to Generate a Random Password from the Linux Command Line Linux 好玩的事儿是达成一件事情可以用上百种方式. ...

  3. 用vue快速开发app的脚手架工具

    前言 多页面应用于结构较于简单的页面,因为简答的页面使用router又过于麻烦.本脚手架出于这样的场景被开发出来. 使用脚手架搭配Hbuilder也同样可以快速使用vue开发安卓和IOS APP. 本 ...

  4. js 数组&字符串 去重

    Array.prototype.unique1 = function() { var n = []; //一个新的临时数组 for(var i = 0; i < this.length; i++ ...

  5. MSF爆破MSSQL

    show options: msf auxiliary(scanner/mssql/mssql_login) > show options Module options (auxiliary/s ...

  6. python基础===python实现截图

    python实现全屏截图: from PIL import ImageGrab im = ImageGrab.grab() im.save('F:\\12.png')

  7. centos rar 文件打开办法

    http://hi.baidu.com/nmxiaoxin/item/7642a139918a95677d034b6a Centos下解压rar.zip文件的方法 ============zip文件的 ...

  8. C基础入门 - 第一章 - C语言绪言

    第1章 C语言绪言 1.1 C语言概述 1.1.1 C语言世界 1.1.2 C语言学习, 能当饭吃吗 1.2 开发环境构建 1.2.1 visual studio安装使用 1.2.2 visual s ...

  9. C# 网络编程小计 20150202

    在学习网络Socket编程之前必须得学会多线程编程,这个是经常会用的到 可参考:http://www.cnblogs.com/GIS_zhou/articles/1839248.html System ...

  10. 动画基础--基于Core Animation(1)

    1.简介 上一篇文章[New learn]动画-基于UIView了解到了一些直接由UIView这个在UIKIT提供的类中提供的一些动画方法. 使用UIView的动画特性已经能够满足我们很多的需求,它是 ...