点分治(树分治)

文章目录

    • 介绍:
    • 题目:
    • 做法:
    • 模板题 [P3806 【模板】点分治1](https://www.luogu.com.cn/problem/P3806)
      • 代码:

介绍:

将原问题分解成若干相同形式,相互独立的子问题,各个击破
一般用来解决有关树上路径的统计和询问

题目:

P4178 Tree
给定一棵 n 个节点的树,每条边有边权,求出树上两点距离小于等于 k 的点对数量。
在这里插入图片描述

做法:

暴力做法;(O(n2))
点分治做法:
选择一个点作为分治中心,令其为rt做dfs。对于一条路径path(u,v),其要么经过rt(即lca(u,v) = = rt),要么在某个子树sub(son[rt])中
把问题形式化为:

solve(T,rt) = 统计T树中经过rt且长度<=k的路径数量

对T数进行分治work(T)的步骤:
1.找到一个分治中心rt
2.ans+=solve(T,rt)//统计答案(统计所有穿过化的路径)
3.对所有rt的子节点v,递归调用work(v)

int work(u)
{rt=find_rt();//找到重心ans=solve(rt);for v∈son[u]:ans+=work(v)return ans;
}

所有合法路径在上述分治过程中被不重不漏地统计到
在这里插入图片描述
详细过程:

在这里插入图片描述
假设高度一共有h层,经过h层递归后到达边界,每一层子问题互不重叠,
每一层都是O(N)
总复杂度:O(H*N)

在这里插入图片描述
我们控制H的大小
(H = 递归的层数)
点分治的复杂度被以下两个条件保证:
1.h=O(log n),每次选T的重心作为rt(重心满足删除后形成的子树大小为之前一半)
2.找重心以及统计答案solve(T,rt)的复杂度=O(size(T)),或者带log,不与n相关
条件1保证每递归一层size(T)减半,log层到达边界
条件2保证每层复杂度为O(n)或者O(nlog n)
点分治总复杂度 O(log n )或O(nlog2n),取决于solve是否带log。

在这里插入图片描述

模板题 P3806 【模板】点分治1

题目描述
给定一棵有 n 个点的树,询问树上距离为 k 的点对是否存在。

代码:

//niiick
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;int read()
{int f=1,x=0;char ss=getchar();while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}return f*x;
}const int inf=10000000;
const int maxn=100010;
int n,m;
struct node{int v,dis,nxt;}E[maxn<<1];
int tot,head[maxn];
int maxp[maxn],size[maxn],dis[maxn],rem[maxn];
int vis[maxn],test[inf],judge[inf],q[maxn];
int query[1010];
int sum,rt;
int ans;void add(int u,int v,int dis)
{E[++tot].nxt=head[u];E[tot].v=v;E[tot].dis=dis;head[u]=tot;
}void getrt(int u,int pa)//求重心 
{size[u]=1; maxp[u]=0;for(int i=head[u];i;i=E[i].nxt) {int v=E[i].v;if(v==pa||vis[v]) continue;getrt(v,u);size[u]+=size[v];maxp[u]=max(maxp[u],size[v]);}maxp[u]=max(maxp[u],sum-size[u]);if(maxp[u]<maxp[rt]) rt=u;
}void getdis(int u,int fa)//每一个子节点到根的距离 
{rem[++rem[0]]=dis[u];for(int i=head[u];i;i=E[i].nxt){int v=E[i].v;if(v==fa||vis[v])continue;dis[v]=dis[u]+E[i].dis;getdis(v,u);}
}void calc(int u)
{int p=0;for(int i=head[u];i;i=E[i].nxt){int v=E[i].v;if(vis[v])continue;rem[0]=0; dis[v]=E[i].dis;getdis(v,u);//处理u的每个子树的disfor(int j=rem[0];j;--j)//遍历当前子树的disfor(int k=1;k<=m;++k)//遍历每个询问{if(query[k]>=rem[j])test[k]|=judge[query[k]-rem[j]];//如果query[k]-rem[j]的路径存在就标记第k个询问}for(int j=rem[0];j;--j)//保存出现过的dis于judge{q[++p]=rem[j];judge[rem[j]]=1;}}for(int i=1;i<=p;++i)//处理完这个子树就清空judgejudge[q[i]]=0;//特别注意一定不要用memeset,会T}void solve(int u)
{   //judge[i]表示到根距离为i的路径是否存在vis[u]=judge[0]=1; calc(u);//处理以u为根的子树for(int i=head[u];i;i=E[i].nxt)//对每个子树进行分治{int v=E[i].v;if(vis[v])continue;sum=size[v]; maxp[rt=0]=inf;//注意sum是以v为根的子树大小getrt(v,0); solve(rt);//在子树中找重心并递归处理}
}int main()
{n=read();m=read();for(int i=1;i<n;++i){int u=read(),v=read(),dis=read();add(u,v,dis);add(v,u,dis);}for(int i=1;i<=m;++i)query[i]=read();//先记录每个询问以离线处理maxp[rt]=sum=n;//第一次先找整棵树的重心getrt(1,0); solve(rt);//对树进行点分治for(int i=1;i<=m;++i){if(test[i]) printf("AYE\n");else printf("NAY\n");}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319109.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET Standard 2.1 公布

原文: Announcing .NET Standard 2.1校对: Cloud自从大约一年前发布 .NET Standard 2.0以来&#xff0c;我们已经向 .NET Core 2.1 发布了两个更新&#xff0c;并即将发布 .NET Core 2.2 。 现在是时候更新 Standard 了&#xff0c;包括一些新的概念以及一些小改进&#xff0c;…

ASP.NET Core中使用GraphQL - 第二章 中间件

前文&#xff1a;ASP.NET Core中使用GraphQL - 第一章 Hello World中间件如果你熟悉ASP.NET Core的中间件&#xff0c;你可能会注意到之前的博客中我们已经使用了一个中间件&#xff0c;这个中间件负责输出了当前查询的结果。中间件的定义&#xff1a;中间件是装载在应用程序管…

ASP.NET Core中Ocelot的使用:基于服务发现的负载均衡

本系列相关文章&#xff1a;《ASP.NET Core中Ocelot的使用&#xff1a;API网关的应用》《ASP.NET Core中Ocelot的使用&#xff1a;基于Spring Clound Netflix Eureka的动态路由》本文将基于前两篇文章所述内容&#xff0c;继续介绍如何在服务发现和动态路由的基础上&#xff0c…

POJ2155 - Matrix(二维树状数组)

POJ2155 - Matrix 文章目录题目题解&#xff1a;代码题目 给你一个二维矩阵&#xff0c;初始化为0&#xff0c;然后可以进行两次操作&#xff1a; C:x,y,x1,y2 对该小矩阵内的数进行取反 Q:查询某个点是0还是1 题解&#xff1a; C是区间修改&#xff0c;Q是单点查询&#xf…

.NET Core2使用Azure云上的Iot-Hub服务

基于工业4.0大背景下的工业物联网是近几年内热门的话题&#xff0c;依靠信息化技术企业可以实现数字化转型&#xff0c;生产可以实现智能化制造&#xff0c;设备可以实现自动化运作。然而&#xff0c;海量的数据采集是整个建设过程的基础环节&#xff0c;如何处理与利用这海量的…

SmartCode.ETL 这不是先有鸡还是蛋的问题!

继国庆节 SmartCode 正式版&#xff08;SmartCode.Generator&#xff09;发布之后&#xff0c;SmartCode 迎来了新的能力 SmartCode.ETL !SmartCode 正式版从开始发布就从未说过自己仅仅是个代码生成器&#xff0c;这点上从我第一次宣布SmartCode正式开源的文章就可以说明&…

dubbo线程池为什么耗尽

文章概述 大家可能都遇到过DUBBO线程池打满这个问题&#xff0c;报错如下&#xff0c;本文我们就一起分析DUBBO线程池打满这个问题。 cause: org.apache.dubbo.remoting.RemotingException: Server side(10.0.0.100,20881) thread pool is exhausted, detail msg:Thread pool …

手把手教你写DI_0_DI是什么?

DI是什么&#xff1f;Dependency Injection 常常简称为&#xff1a;DI。它是实现控制反转&#xff08;Inversion of Control – IoC&#xff09;的一个模式。fowler 大大大神 “几十年”前的经典文章 https://www.martinfowler.com/articles/injection.html 说的很清楚。“几十…

C++顺序创建txt文件

今天下午在对拍数据的时候感觉好麻烦。。 一次次手调文件名称&#xff0c;突然想起可以直接写段程序集中操作 顺序输出 #include <iostream> #include <fstream> #include<string> using namespace std;int main () {ofstream File;for(int i0;i<3;i){str…

使用Visual Studio Code开发.NET Core看这篇就够了

在本文中&#xff0c;我将带着大家一步一步的通过图文的形式来演示如何在Visual Studio Code中进行.NET Core程序的开发&#xff0c;测试以及调试。尽管Visual Studio Code的部分功能还达不到Visual Studio的水平&#xff0c;但它实际上已经足够强大来满足我们的日常开发。而且…

手把手教你写DI_3_小白徒手支持 Singleton 和 Scoped 生命周期

在上一节&#xff1a;手把手教你写DI_2_小白徒手撸构造函数注入浑身绷带的小白同学&#xff1a;我们继续开展我们的工作&#xff0c;大家都知道 Singleton是什么&#xff0c;就是全局只有一个呗&#xff0c;我们就先从它开始&#xff0c;这个多简单&#xff0c;我们找个字典放这…

手把手教你写DI_2_小白徒手撸构造函数注入

在上一节&#xff1a;手把手教你写DI_1_DI框架有什么&#xff1f;我们已经知道我们要撸哪些东西了那么我们开始动工吧&#xff0c;这里呢&#xff0c;我们找小白同学来表演下小白同学 &#xff1a;我们先定义一下我们的广告招聘纸有什么&#xff1a;好&#xff0c;我们实现两种…

服务器win2008 R2 x64 部署ASP.net core到IIS 并解决 HTTP Error 502.5 的问题

1、发布网站 &#xff1b;2、安装 vc_redist.x64 (Visual C Redistributable for Visual Studio 2015) 新装的系统没装的补丁&#xff0c;装过略过&#xff1b;3、安装WindowsHosting &#xff1a;如&#xff1a; dotnet-hosting-2.1.3-win &#xff1b;4、安装.Net Core SDK&…

Data Structure Problem

试题链接 题目描述 题意&#xff1a; 有两个序列&#xff0c; 操作1是将a序列的第x位改成y 操作2是将b序列的第x位改成y 操作3是找到一个cx&#xff0c;满足递推式c00&#xff0c;ci max(ci-1bi&#xff0c;ai) 题解&#xff1a; 官方题解 说实话我没大看懂。。。 题是我同…

定制Ocelot来满足需求

这篇文章&#xff0c;我们将从Ocelot的中间件源码分析&#xff0c;目前Ocelot已经实现那些功能&#xff0c;还有那些功能在我们实际项目中暂时还未实现&#xff0c;如果我们要使用这些功能&#xff0c;应该如何改造等方面来说明。一、Ocelot源码解读在使用一个组件前&#xff0…

【.NET Core项目实战-统一认证平台】第一章 功能及架构分析

从本文开始&#xff0c;我们正式进入项目研发阶段&#xff0c;首先我们分析下统一认证平台应该具备哪些功能性需求和非功能性需求&#xff0c;在梳理完这些需求后&#xff0c;设计好系统采用的架构来满足已有的需求和未来的扩展应用。1 功能性需求统一认证平台应该具备以下基本…

Shift and Reverse

题目链接 题意&#xff1a; 一个序列a1&#xff0c;a2&#xff0c;a3…an 选择一个i&#xff0c;然后将序列改成ai,ai-1,…a1,an,an-1,…ai1 可以进行无数次这样的操作 问&#xff1a;最多有多少不同的序列产生&#xff1f;&#xff08;答案mod1e97&#xff09; 题解&#xf…

Redis基本使用及百亿数据量中的使用技巧分享

作者&#xff1a;依乐祝原文地址&#xff1a;https://www.cnblogs.com/yilezhu/p/9941208.html作者&#xff1a;大石头时间&#xff1a;2018-11-10 晚上20&#xff1a;00地点&#xff1a;钉钉群&#xff08;组织代码BKMV7685&#xff09;QQ群&#xff1a;1600800内容&#xff1…

Subsequence Pair

题目 题目描述 题意&#xff1a; X和Y两个字符串&#xff0c;两个字符串各取子序列X1和Y1&#xff0c;问X1<Y1的情况下X1和Y1的长度和最长是多少&#xff1f; 比如例子&#xff1a; zazxwabzczazazd abcaa 第一个字符串选取子序列为azxwabzczazazd 第二个为bcaa azxwabzc…

【.NET Core项目实战-统一认证平台】第三章 网关篇-数据库存储配置(1)

本篇将介绍如何扩展Ocelot中间件实现自定义网关&#xff0c;并使用2种不同数据库来演示Ocelot配置信息存储和动态更新功能&#xff0c;内容也是从实际设计出发来编写我们自己的中间件&#xff0c;本文内容涵盖设计思想内容和代码内容&#xff0c;我希望园友们最好跟着我这个文章…