题目链接

要求的和、最大值、最小值好像都可以通过O(n)的树形DP做,总询问点数<=2n。

于是建虚树就可以了。具体DP见DP()函数,维护三个值sum[],mx[],mn[]。

sum[]要开longlong!。。

//108172kb	2564ms(又是Rank4...)
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 1000000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e6+5,M=N<<1,INF=5e8; int n,Q,K,A[N],Enum,H[N],nxt[M],to[M],val[M],dep[N],tp[N],top,sk[N],dfn[N],Index,fa[N],son[N],sz[N],mn[N],mx[N],Min,Max;
LL Sum,sum[N];
bool tag[N];
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline bool cmp_dfn(const int &a,const int &b){
return dfn[a]<dfn[b];
}
inline void Add_direct(int u,int v){
to[++Enum]=v, nxt[Enum]=H[u], val[Enum]=dep[v]-dep[u], H[u]=Enum;
}
inline void AddEdge(int u,int v){
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void DFS1(int x)
{
int mx=0; sz[x]=1;
for(int v,i=H[x]; i; i=nxt[i])
if((v=to[i])!=fa[x])
{
fa[v]=x, dep[v]=dep[x]+1, DFS1(v), sz[x]+=sz[v];
if(mx<sz[v]) mx=sz[v], son[x]=v;
}
}
void DFS2(int x,int _tp)
{
dfn[x]=++Index, tp[x]=_tp;
if(son[x])
{
DFS2(son[x],_tp);
for(int i=H[x]; i; i=nxt[i])
if(to[i]!=fa[x]&&to[i]!=son[x]) DFS2(to[i],to[i]);
}
}
int LCA(int u,int v)
{
while(tp[u]!=tp[v]) dep[tp[u]]>dep[tp[v]]?u=fa[tp[u]]:v=fa[tp[v]];
return dep[u]>dep[v]?v:u;
}
void Insert(int p)
{
if(top==1) {sk[++top]=p; return;}
int lca=LCA(sk[top],p);
// if(lca==sk[top]) {sk[++top]=p; return;}
while(dfn[sk[top-1]]>=dfn[lca]) Add_direct(sk[top],sk[top--]);
if(lca!=sk[top] && dfn[sk[top-1]]<dfn[lca]) Add_direct(lca,sk[top]), sk[top]=lca;
sk[++top]=p;
}
void DP(int x)
{
sum[x]=0;
if(tag[x]) mn[x]=0, mx[x]=0/*可以以此为一端点*/, sz[x]=1;
else mn[x]=INF, mx[x]=-INF, sz[x]=0;
for(int v,i=H[x]; i; i=nxt[i])
{
DP(v=to[i]);
Min=std::min(Min, mn[x]+mn[v]+val[i]), mn[x]=std::min(mn[x], mn[v]+val[i]);
Max=std::max(Max, mx[x]+mx[v]+val[i]), mx[x]=std::max(mx[x], mx[v]+val[i]);
Sum+=1ll*sz[x]*(sum[v]+val[i]*sz[v])+1ll*sz[v]*sum[x];//之前的此时会被统计sz[v]次,v子树被统计sz[x]次 //long long!
sum[x]+=sum[v]+val[i]*sz[v], sz[x]+=sz[v];
}
tag[x]=H[x]=0;
} int main()
{
n=read();
for(int i=1; i<n; ++i) AddEdge(read(),read());
DFS1(1), DFS2(1,1), Enum=0, memset(H,0,sizeof H);// memset(sz,0,sizeof sz);
Q=read();
while(Q--)
{
K=read();
for(int i=1; i<=K; ++i) tag[A[i]=read()]=1;
std::sort(A+1,A+1+K,cmp_dfn);
sk[top=1]=1;
if(A[1]==1) for(int i=2; i<=K; ++i) Insert(A[i]);//以1为根,注意不要加1两次。。
else for(int i=1; i<=K; ++i) Insert(A[i]);
while(--top) Add_direct(sk[top],sk[top+1]);//! Sum=0, Min=INF, Max=-INF, DP(1);
printf("%lld %d %d\n",Sum,Min,Max);
Enum=0;// for(int i=1; i<=K; ++i) H[A[i]]=0;
}
return 0;
}

BZOJ.3611.[HEOI2014]大工程(虚树 树形DP)的更多相关文章

  1. bzoj 3611: [Heoi2014]大工程 虚树

    题目: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 ...

  2. BZOJ 3611 [Heoi2014]大工程 ——虚树

    虚树第二题.... 同BZOJ2286 #include <map> #include <cmath> #include <queue> #include < ...

  3. luogu P4103 [HEOI2014]大工程 虚树 + 树形 DP

    Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道.  我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上.  在 2 个国家 a,b 之间建一条新通 ...

  4. 洛谷P4103 [HEOI2014]大工程(虚树 树形dp)

    题意 链接 Sol 虚树. 首先建出虚树,然后直接树形dp就行了. 最大最小值直接维护子树内到该节点的最大值,然后合并两棵子树的时候更新一下答案. 任意两点的路径和可以考虑每条边两边的贡献,\(d[x ...

  5. bzoj 3611[Heoi2014]大工程 虚树+dp

    题意: 给一棵树 每次选 k 个关键点,然后在它们两两之间 新建 C(k,2)条 新通道. 求: 1.这些新通道的代价和 2.这些新通道中代价最小的是多少 3.这些新通道中代价最大的是多少 分析:较常 ...

  6. bzoj 3611 [Heoi2014]大工程(虚树+DP)

    3611: [Heoi2014]大工程 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 408  Solved: 190[Submit][Status] ...

  7. bzoj 3611(洛谷 4103) [Heoi2014]大工程——虚树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3611 https://www.luogu.org/problemnew/show/P4103 ...

  8. bzoj 3611: [Heoi2014]大工程 && bzoj 2286: [Sdoi2011消耗战

    放波建虚树的模板. 大概是用一个栈维护根节点到当前关键点的一条链,把其他深度大于lca的都弹出去. 每次做完记得复原. 还有sort的时候一定要加cmp!!! bzoj 3611 #include&l ...

  9. bzoj 3611: [Heoi2014]大工程

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...

随机推荐

  1. 工具_HBuilder工具使用技巧

    https://www.cnblogs.com/xiaohouzai/p/7696152.html

  2. Sicily 1211. 商人的宣传

    题目链接:http://soj.me/1211 Description Bruce是K国的商人,他在A州成立了自己的公司,这次他的公司生产出了一批性能很好的产品,准备宣传活动开始后的第L天到达B州进行 ...

  3. 【算法学习】【洛谷】cdq分治 & P3810 三维偏序

    cdq是何许人也?请参看这篇:https://wenku.baidu.com/view/3b913556fd0a79563d1e7245.html. 在这篇论文中,cdq提出了对修改/询问型问题(Mo ...

  4. 利用Mysql5.7的新特性实现多机房高可用架构【转】

    再牛逼的架构也敌不过挖掘机,无论单机房内你的架构多么的高可用,多么的完善,当挖掘机挖下去那一瞬间,都是扯蛋,楼主所在的公司也被挖掘机挖断过光纤.电力线. 为什么大家都在谈论服务冗余,缓存击穿等高可用时 ...

  5. Tomcat的JVM设置和连接数设置

    Windows环境下修改“%TOMCAT_HOME%\bin\catalina.bat”文件,在文件开头增加如下设置:set JAVA_OPTS=-Xms256m -Xmx512m Linux环境下修 ...

  6. 关于vc++ 6.0 编译器,点打开文件时自动关闭

    装好VC++ 6.0后,点打开文件时编译器会自动关闭掉,然后在网上找到各位大神写的资料,果然是因为之前有安装vs2010冲突的缘故,然后http://download.csdn.net/source/ ...

  7. 数据科学实战手册(R+Python)书中引用资料网址

    本文会持续将<数据科学实战手册(R+Python)>一书中的附带参考资料网址手打出来, 方便访问. 由于书中的参考资料网址太多, 这个文档将可能花费一段时间才能完成. 第一章 P7  Rs ...

  8. robotframework-ride多次运行,有时候不显示日志信息

    解决方法: 修改"C:\Python27\lib\site-packages\robotide\contrib\testrunner\testrunner.py"文件pop方法中  ...

  9. 字体格式类型(.eot/.otf/.woff/.svg)

    @font-face语句是css中的一个功能模块,用于实现网页字体多样性的模块(设计者可随意指定字体,不需要考虑浏览者电脑上是否安装). @font-face文件 而由于网页中使用的字体类型,也是各浏 ...

  10. thinkphp辅助方法,数据库操作