P4103 [HEOI2014]大工程 虚树 + dp

传送门

文章目录

  • 题意:
  • 思路:

题意:

在这里插入图片描述

在这里插入图片描述

思路:

简化一下题意就是求树上给定点集中每两个点之间的距离之和,相距最远的点,相距最近的点。
对于距离和我们统计一下边的贡献就好啦,边两头的sizesizesize乘起来就好了。对于相距最远的点和相距最近的点,我们可以设f[x]f[x]f[x]表示xxx子树中距离xxx最近的关键点的距离,g[x]g[x]g[x]表示xxx子树中距离xxx最远的关键点的距离,那么f[x]=min(f[x],f[v]+w[i]),g[x]=max(g[x],g[v]+w[i])f[x]=min(f[x],f[v]+w[i]),g[x]=max(g[x],g[v]+w[i])f[x]=min(f[x],f[v]+w[i]),g[x]=max(g[x],g[v]+w[i]),当xxx这个点是关键点的时候,f[x]=0f[x]=0f[x]=0,让后定义ans2,ans3ans2,ans3ans2,ans3分别表示第二第三种答案,ans2=min(ans2,f[x]+f[v]+w[i]),ans3=max(ans3,g[x]+g[v]+w[i])ans2=min(ans2,f[x]+f[v]+w[i]),ans3=max(ans3,g[x]+g[v]+w[i])ans2=min(ans2,f[x]+f[v]+w[i]),ans3=max(ans3,g[x]+g[v]+w[i]),当然算ans2,ans3ans2,ans3ans2,ans3的时候需要在f,gf,gf,g更新之前算。
但是有一个很大的问题,就是我们每次都遍历所有树的话复杂度是O(nq)O(nq)O(nq)的,但是∑k≤2∗n\sum k\le2*nk2n,所以我们每次都建一颗虚树,复杂度就是O(q+n)O(q+n)O(q+n)的了。

不用看dfs2,dfs3dfs2,dfs3dfs2,dfs3,写的跟shi一样。

// Problem: P4103 [HEOI2014]大工程
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4103
// Memory Limit: 500 MB
// Time Limit: 4000 ms
// 
// Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;// char buf[1<<23],*p1=buf,*p2=buf;
// #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
// inline bool ig(char c){return c>=48&&c<=57;}
// inline void read(int &oi){char c;int f=1,res=0;while(c=gc(),(!ig(c))&&c^'-');c^'-'?res=(c^48):f=-1;while(c=gc(),ig(c))res=res*10+(c^48);oi=f*res;}
// inline void print(int oi){if(oi<0)putchar('-'),oi=~oi+1;if(oi>9)print(oi/10);putchar(oi%10+48);}
// inline void print(LL oi){if(oi<0)putchar('-'),oi=~oi+1;if(oi>9)print(oi/10);putchar(oi%10+48);}
// template <class T>
bool read(T &ret)
{char c;int sgn;T bit=0.1;if(c=getchar(), c==EOF)return 0;while(c!='-' && c!='.' && (c<'0' || c>'9'))c=getchar();sgn=(c=='-')? -1:1;ret=(c=='-')? 0:(c-'0');while(c=getchar(), c>='0' && c<='9')ret=ret*10+(c-'0');if(c==' ' || c=='\n'){ret*=sgn;return 1;}while(c=getchar(), c>='0' && c<='9')ret+=(c-'0')*bit, bit/=10;ret*=sgn;return 1;
}inline void out(LL x)//����
{if(x>9)out(x/10);putchar(x%10+'0');
}int n,m;
int depth[N],fa[N][20],dfn[N],idx;
int a[N],tot;
int stk[N],top;
int has[N],se[N],dp1[N],dp2[N];
vector<PII>v[N];
LL ans1;
int ans2,ans3;void dfs1(int u,int f) {fa[u][0]=f; dfn[u]=++idx;depth[u]=depth[f]+1;for(int i=1;i<=18;i++) fa[u][i]=fa[fa[u][i-1]][i-1];for(auto x:v[u]) {if(x.X==f) continue;dfs1(x.X,u);}
}int lca(int a,int b) {if(depth[a]<depth[b]) swap(a,b);for(int i=18;i>=0;i--) if(depth[fa[a][i]]>=depth[b])a=fa[a][i];if(a==b) return a;for(int i=18;i>=0;i--) if(fa[a][i]!=fa[b][i]) a=fa[a][i],b=fa[b][i];return fa[a][0];
}bool cmp(int a,int b) {return dfn[a]<dfn[b];
}void insert(int x) {if(!top) stk[++top]=x;else {int father=lca(x,stk[top]);while(top>1&&depth[father]<depth[stk[top-1]]) {v[stk[top-1]].pb({stk[top],depth[stk[top]]-depth[stk[top-1]]}),top--;}if(depth[father]<depth[stk[top]]) v[father].pb({stk[top],depth[stk[top]]-depth[father]}),top--;if(!top||stk[top]!=father) stk[++top]=father;stk[++top]=x;}
}// void dfs2(int u,int f) {// if(has[u]) se[u]=1;// int mx1=0,mx2=0;// for(auto x:v[u]) {// if(x.X==f) continue;// dfs2(x.X,u);// se[u]+=se[x.X];// ans1+=1ll*se[x.X]*(tot-se[x.X])*x.Y;//算边的贡献// int now=dp[x.X]+x.Y;// if(now>mx1) mx2=mx1,mx1=now;// else if(now>mx2) mx2=now; // }// //以这个点为两个链的连接点,所以这个点是不是关键点不重要,// //重要的是有两个链,而链的尽头是关键点// if(mx2>0) ans2=max(ans2,1ll*mx1+mx2);// else if(has[u]) ans2=max(ans2,1ll*mx1+mx2);//如果是关键点,那么可以以他为链的一端// dp[u]=mx1;
// }
// 
// void dfs3(int u,int f) {// if(has[u]) {// ff[u]=u;// for(auto x:v[u]) {// if(x.X==f) continue;// dfs3(x.X,u);// ans3=min(ans3,depth[ff[x.X]]-depth[u]);// }// } else {// int mi1,mi2; mi1=mi2=INF;// for(auto x:v[u]) {// if(x.X==f) continue;// dfs3(x.X,u);// if(mi1>depth[ff[x.X]]) mi2=mi1,mi1=depth[ff[x.X]],ff[u]=ff[x.X];// else if(mi2>depth[ff[x.X]]) mi2=depth[ff[x.X]];// }// ans3=min(ans3,mi2+mi1-2*depth[u]);// }
// }
// 
void dfs4(int u,int f) {if(has[u]) se[u]=1;dp1[u]=has[u]? 0:1e9;dp2[u]=0;for(auto x:v[u]) {if(x.X==f) continue;dfs4(x.X,u);ans1+=1ll*se[x.X]*(tot-se[x.X])*x.Y;if(se[u]>0) {ans2=min(ans2,dp1[u]+dp1[x.X]+x.Y);ans3=max(ans3,dp2[u]+dp2[x.X]+x.Y);}dp1[u]=min(dp1[u],dp1[x.X]+x.Y);dp2[u]=max(dp2[u],dp2[x.X]+x.Y);se[u]+=se[x.X];}
}void clear(int u,int f) {has[u]=se[u]=dp1[u]=dp2[u]=0;for(auto x:v[u]) {if(x.X==f) continue;clear(x.X,u);}v[u].clear();
}int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);//rd_ac();read(n);for(int i=1;i<=n-1;i++) {int a,b; read(a); read(b);v[a].pb({b,1}); v[b].pb({a,1});}dfs1(1,0);for(int i=1;i<=n;i++) v[i].clear();read(m);while(m--) {read(tot);for(int i=1;i<=tot;i++) read(a[i]),has[a[i]]=1;sort(a+1,a+1+tot,cmp);top=0; ans1=ans3=0; ans2=INF;if(a[1]!=1) stk[++top]=1;for(int i=1;i<=tot;i++) insert(a[i]);while(top>1) v[stk[top-1]].pb({stk[top],depth[stk[top]]-depth[stk[top-1]]}),top--;//dfs2(1,0); dfs3(1,0);dfs4(1,0);//printf("%lld %d %d\n",ans1,ans2,ans3);out(ans1); putchar(' ');out(ans2); putchar(' ');out(ans3); putchar('\n');clear(1,0);}return 0;
}
/**/

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

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

相关文章

【翻译】Keras.NET简介 - 高级神经网络API in C#

用C#&#xff0c;远离996Keras.NETKeras.NET是一个高级神经网络API&#xff0c;它使用C#编写&#xff0c;并带有Python绑定&#xff0c;可以在Tensorflow、CNTK或Theano上运行。其关注点是实现快速实验。因为做好研究的关键是&#xff1a;能在尽可能短的时间内从一个想法发展出…

TIOBE 6月排行:C# 以微弱的优势超过了 Visual Basic .NET 的排名,再次进入 TOP 5

月经贴警告……TIOBE 编程语言排行榜 7 月更新已公布&#xff0c;排名前十的分别是&#xff1a;Java, C, Python, C, C#, Visual Basic .NET, JavaScript, PHP, SQL 和汇编语言。和上个月的不同之处主要是 C# 以微弱的优势超过了 Visual Basic .NET 的排名&#xff0c;再次进入…

用.NET Core实现一个类似于饿了吗的简易拆红包功能

需求说明以前很讨厌点外卖的我&#xff0c;最近中午经常点外卖&#xff0c;因为确实很方便&#xff0c;提前点好餐&#xff0c;算准时间&#xff0c;就可以在下班的时候吃上饭&#xff0c;然后省下的那些时间就可以在中午的时候多休息一下了。点餐结束后&#xff0c;会有一个好…

kubernetes实战篇之helm示例yaml文件文件详细介绍

前面完整示例里,我们主要讲解helm打包,部署,升级,回退等功能,关于这里面的文件只是简单介绍,这一节我们详细介绍一下这里面的文件,以方便我们参照创建自己的helm chart.Helm Chart 结构Chart 目录结构mychart/ Chart.yaml LICENSE README.md values.yaml requirements.yam…

P4309 [TJOI2013]最长上升子序列 平衡树 + dp

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 注意到一个很关键的条件&#xff0c;每次插入iii&#xff0c;而iii是递增的&#xff0c;也就是说插入iii之后只会从前面的最大值转移过来&#xff0c;所以我们现在只需要维护插入操作即可&…

【AGC035C】Skolem XOR Tree【异或】【构造】

传送门 题意&#xff1a;给定nnn&#xff0c;构造或判断无法构造一个2n2n2n个结点的树&#xff0c;其中结点iii和ininin的权值为iii,且所有iii和ininin路径权值异或和等于iii。 注意到 2i⊕2i112i\oplus2i112i⊕2i11&#xff0c;然后可以脑补出 然而111没处理 发现1⊕2⊕301\…

ASP.NET Core 管道再探

几乎任何服务器端处理环境都有自己的直通组件管道&#xff0c;用于检查、重路由或修改传入请求和传出响应。经典 ASP.NET 围绕 HTTP 模块理念进行排列&#xff0c;而 ASP.NET Core 采用基于中间件组件的更现代的体系结构。最终目的是相同的 - 允许可配置的外部模块以请求&#…

GRPC与.net core

QQ讨论群&#xff1a;953553560正文系列章节GRPC与.net coreGRPC截止时间与元数据GRPC与netcore IdentityGRPC与netcore IdentityServer4概述GRPC的数据交互模式有&#xff1a;1.单项RPC&#xff0c;最简单的数据交换方式&#xff0c;客户端发出单个请求&#xff0c;收到单个响…

程序员修神之路--做好分库分表其实很难之一

点击上方“蓝字”带你去看小星星菜哥&#xff0c;领导让我开发新系统了这么说领导对你还是挺信任的呀~必须的&#xff0c;为了设计好这个新系统&#xff0c;数据库设计我花了好多心思呢做一个系统我觉得不应该从数据库入手&#xff0c;应该从设计业务模型开始&#xff0c;先不说…

Office 365开发者的前端必备课程

这篇文章其实不仅仅是写给Office 365开发者的&#xff0c;但对于广大的Office 365开发者来说确实相当重要的。这里提到的Office 365开发者&#xff0c;包括了Office Add-ins&#xff0c;SharePoint Add-ins&#xff0c;Microsoft Graph&#xff0c;Microsoft Teams的开发者。我…

【CF1338C】Perfect Triples【位运算】【构造】

传送门 题意&#xff1a;有一序列SSS由下列方式生成&#xff1a; 找到字典序最小的正整数(a,b,c)(a,b,c)(a,b,c)&#xff0c;满足a,b,ca,b,ca,b,c不在SSS中且a⊕b⊕c0a\oplus b\oplus c0a⊕b⊕c0,其中⊕\oplus⊕为异或将a,b,ca,b,ca,b,c加入SSS重复第一步 TTT组数据&#xff…

.NET开发框架(五)-IIS上部署ASP.NET Core项目教程

在之前教程中&#xff0c;我们分享了框架的功能与视频演示介绍(文尾底部提供往期教程快捷链接)系列教程&#xff1a;从初学者到架构师的一步步蜕变本篇经验将和大家介绍如何在IIS上部署ASP.NET Core项目&#xff0c;希望对初学.NET CORE的童靴入门有所帮助&#xff01;1、打开V…

P4146 序列终结者 平衡树 + lazy维护

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 平衡树裸题&#xff0c;直接维护俩lazylazylazy就行了。 需要注意的是&#xff0c;只有儿子节点存在的时候才能更新&#xff0c;不然更新到000号节点之后&#xff0c;给000号点加上了奇怪的…

.NET开发框架(四)-服务器IIS实践教程

前三篇教程中&#xff0c;我们分享了框架的功能与视频演示介绍(文尾底部提供往期教程快捷链接)&#xff0c;今天开始我们进入实践教程&#xff0c;从0开始教学&#xff0c;让你从新手到架构师之兑变&#xff0c;目前已经重置了一台服务器&#xff0c;从安装与配置各组件开始学习…

.NET Core IdentityServer4实战 第六章-Consent授权页

在identityServer4中登陆页面只要是成功了&#xff0c;就会注册一个Cookie在服务器资源上&#xff0c;像现在大部分的网站第三方授权&#xff0c;都是经过一个页面&#xff0c;然后选需要的功能&#xff0c;IdentityServer4也给我们提供了&#xff0c;只要你登陆成功,就会跳转到…

GitHub的CI实践(xUnit / OpenCover /Appveyor / Coveralls.net)

最近利用业余时间实现.ner core 版本的 casbin &#xff0c;即 Casbin.NET。之前的CI都使用的是公司搭建的jenkins和gitlab-runner&#xff0c;对开源社区的工具链并不是很熟悉&#xff0c;在casbin的原作者(hsluoyz )的“要求”下&#xff0c;只能被迫在项目的README.md加入下…

P4847 银河英雄传说V2 非旋treap

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 让我们分析一下题目需要实现什么操作&#xff1a; (1)(1)(1)将某个序列放到某个的后面&#xff0c;也就是合并两个序列。 (2)(2)(2)将一个序列从某处断开。 (3)(3)(3)查询某个序列的一段和…

小白开学Asp.Net Core 《五》

小白开学Asp.Net Core《五》—— 使用.Net Core MVC Filter一、简介今天在项目&#xff08;https://github.com/AjuPrince/Aju.Carefree&#xff09;做登陆权限时&#xff0c;用到了Filter&#xff0c;现将Filer的使用做以下记录。二、Filter 简介Filter俗称过滤器&#xff0c;…

P5217 贫穷 平衡树

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 本来是不想写数据结构了&#xff0c;因为明天打蓝桥了&#xff0c;想放松一下&#xff0c;但是看到这个题感觉写起来挺简单的&#xff0c;就试了试&#xff0c;结果… 首先看一下他的操作…

高性能微服务网关.NETCore客户端Kong.Net开源发布

前言项目地址&#xff1a;https://github.com/lianggx/Kong.Net你的支持使我们更加强大&#xff0c;请单击 star 让更多的 .NETCore 认识它。拥抱开源的脚步&#xff0c;我们从来都是一直在路上&#xff1b;.NETCore作为后起之秀&#xff0c;带给我们太多的惊喜和感动&#xff…