和BZOJ消耗站一样,先将那个询问的简图构建出来,然后就是简单的树形DP。

(倍增数组开小了,然后就狂WA,自己生成的极限数据深度又没有那么高,链又奇迹般正确)

 #include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define oo 0x3f3f3f3f3f3f3f3f
#define N 1000010
#define P 19
using namespace std; typedef long long dnt; int n, m;
vector<int> g[N];
int dfn[N], anc[N][P+], dep[N], idc;
int head[N], ikey[N], dest[N+N], next[N+N], etot;
dnt dp[N][];
int qcnt, aa[N], stk[N], top;
dnt ans[]; void adde( int u, int v ) {
etot++;
next[etot] = head[u];
dest[etot] = v;
head[u] = etot;
}
void dfs( int u ) {
dfn[u] = ++idc;
for( int p=; p<=P; p++ )
anc[u][p] = anc[anc[u][p-]][p-];
for( int t=; t<g[u].size(); t++ ) {
int v=g[u][t];
if( v==anc[u][] ) continue;
anc[v][] = u;
dep[v] = dep[u]+;
dfs(v);
}
}
bool cmp( int u, int v ) {
return dfn[u]<dfn[v];
}
int lca( int u, int v ) {
if( dep[u]<dep[v] ) swap(u,v);
int t=dep[u]-dep[v];
for( int p=; t; t>>=,p++ )
if( t& ) u=anc[u][p];
if( u==v ) return u;
for( int p=P; p>= && anc[u][]!=anc[v][]; p-- )
if( anc[u][p]!=anc[v][p] ) u=anc[u][p], v=anc[v][p];
return anc[u][];
}
void build() {
stk[top=] = ;
head[] = ; sort( aa+, aa++qcnt, cmp ); etot = ;
for( int i=-(aa[]!=); i<=qcnt; i++ ) {
int ca=lca(aa[i],stk[top]);
while( dep[ca]<dep[stk[top]] ) {
int u;
u = stk[top--];
if( dep[ca]>=dep[stk[top]] ) {
if( ca!=stk[top] ) {
stk[++top] = ca;
head[ca] = ;
}
adde( stk[top], u );
break;
}
adde( stk[top], u );
}
stk[++top] = aa[i];
head[aa[i]] = ;
}
for( int i=top; i>=; i-- )
adde( stk[i-], stk[i] );
}
dnt sml, big, sum, cnt;
void dodp( int u ) {
if( ikey[u] ) {
dp[u][] = ;
dp[u][] = ;
dp[u][] = ;
dp[u][] = ;
} else {
dp[u][] = oo;
dp[u][] = -oo;
dp[u][] = ;
dp[u][] = ;
}
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t];
dnt w=dep[v]-dep[u];
dodp(v);
dp[u][] = min( dp[u][], dp[v][]+w );
dp[u][] = max( dp[u][], dp[v][]+w );
dp[u][] += dp[v][];
dp[u][] += dp[v][]+w*dp[v][];
}
if( ikey[u] ) {
sml = ;
big = ;
sum = ;
cnt = ;
} else {
sml = oo;
big = -oo;
sum = ;
cnt = ;
}
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t];
dnt w=dep[v]-dep[u];
ans[] = min( ans[], sml+w+dp[v][] );
ans[] = max( ans[], big+w+dp[v][] );
ans[] += cnt*(dp[v][]+w*dp[v][]) + sum*dp[v][];
sml = min( sml, dp[v][]+w );
big = max( big, dp[v][]+w );
cnt += dp[v][];
sum += dp[v][]+w*dp[v][];
}
}
int main() {
scanf( "%d", &n );
for( int i=,u,v; i<n; i++ ) {
scanf( "%d%d", &u, &v );
g[u].push_back( v );
g[v].push_back( u );
}
anc[][] = ;
dep[] = ;
dfs();
scanf( "%d", &m );
for( int i=; i<=m; i++ ) {
scanf( "%d", &qcnt );
for( int j=; j<=qcnt; j++ )
scanf( "%d", aa+j ); if( qcnt== ) {
printf( "0 0 0\n" );
continue;
} build(); for( int j=; j<=qcnt; j++ )
ikey[aa[j]] = ;
ans[] = oo;
ans[] = ;
ans[] = ;
dodp();
for( int j=; j<=qcnt; j++ )
ikey[aa[j]] = ; printf( "%lld %lld %lld\n", ans[], ans[], ans[] );
}
}

bzoj 3611的更多相关文章

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

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

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

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

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

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

  4. bzoj 3611: [Heoi2014]大工程

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

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

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

  6. BZOJ.3611.[HEOI2014]大工程(虚树 树形DP)

    题目链接 要求的和.最大值.最小值好像都可以通过O(n)的树形DP做,总询问点数<=2n. 于是建虚树就可以了.具体DP见DP()函数,维护三个值sum[],mx[],mn[]. sum[]要开 ...

  7. 大工程(bzoj 3611)

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

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

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

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

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

随机推荐

  1. Linux Module框架【转】

    转自:http://www.cnblogs.com/LittleHann/p/4558719.html catalog 1. 概述 2. 使用模块 3. 插入和删除模块 4. 自动化与热插拔 5. 版 ...

  2. linux通配符,grep和 egrep区别

    其实主要是正则表达式中的一些特殊语法.在网上找的几篇文章,截取相关部分贴在了下面,方便以后翻阅. 参考:http://hi.baidu.com/sei_zhouyu/item/c18e1a950d2e ...

  3. 如何提高单片机Flash的擦写次数

    所谓提高flash的擦写次数,并不是真正的提高flash擦写次数,而是通过以"空间换时间"概念,在软件上实现“操作的次数大于其寿命”.详见链接: http://bbs.eeworl ...

  4. Java集合Map与其子类回顾

    接10月12号昨天的笔记,今天继续回顾集合中的Map集合. 一.集合工具操作类Collections 问题:collection和collections的区别? 1.collection是单列集合的顶 ...

  5. Unix IPC之共享内存区(1)

    1 共享内存区 共享内存区是可用IPC形式中最快的,只有映射和解除映射需要进入内核的系统调用,映射后对共享内存区的访问和修改不再需要系统调用(内核只要负责好页表映射和处理页面故障即可),但通常需要同步 ...

  6. Failed to create the Java Virtual Machine

    启动Zend Studio时出现Failed to create the Java VIrtual Machine 解决办法如下.打开安装目录下的ZendStudio.ini配置文件,作如下修改: 说 ...

  7. NSPredicate用法总结(Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取)

    简述:Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取. 定义(最常用到的方法): NSPredicate *ca = [NSPred ...

  8. 一步一步学习IdentityServer4 (3)自定登录界面并实现业务登录操作

    IdentityServer4 相对 IdentityServer3 在界面上要简单一些,拷贝demo基本就能搞定,做样式修改就行了 之前的文章已经有登录Idr4服务端操作了,新建了一个自己的站点 L ...

  9. hdu 5446(2015长春网络赛J题 Lucas定理+中国剩余定理)

    题意:M=p1*p2*...pk:求C(n,m)%M,pi小于10^5,n,m,M都是小于10^18. pi为质数 M不一定是质数 所以只能用Lucas定理求k次 C(n,m)%Pi最后会得到一个同余 ...

  10. hdu 4813(2013长春现场赛A题)

    把一个字符串分成N个字符串 每个字符串长度为m Sample Input12 5 // n mklmbbileay Sample Outputklmbbileay # include <iost ...