[POI2013]Polaryzacja

题目大意:

给定一棵\(n(n\le250000)\)个点的树,可以对每条边定向成一个有向图,这张有向图的可达点对数为树上有路径从\(u\)到达\(v\)的点对\((u,v)\)个数。求最小可达点对数和最大可达点对数。

思路:

显然最小可达点对数是\(n-1\)。一种构造就是根结点全是入边,与根结点相邻的点全是出边……以此类推。最后相邻的点对会被统计一次,其余的均不会被统计。

对于最大可达点对数,一定存在一种方案,使得树根是树的任意一个重心时,将所有子树分成两部分,一部分有\(k\)个点,另一部分有\((n-k-1)\)个点,答案就是\(\max\{(n-k-1)k+\sum(dep(i)-1)\}\)。

具体证明略。

我们可以用一个背包来求出所有可能的\(k\),但是时间复杂度是\(\mathcal O(n^2)\),就算使用bitset优化也无济于事。

因此我们可以将所有子树\(size\)按照大小分开转移。\(>\sqrt n\)的不超过\(\sqrt n\)个,可以直接暴力转移;\(\le\sqrt n\)的按照大小分组一起转移,具体转移时可以按照二进制拆分。

时间复杂度\(\mathcal O(\frac{n\sqrt n}\omega)\)。

源代码:

#include<cmath>
#include<cstdio>
#include<cctype>
#include<vector>
#include<bitset>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef long long int64;
const int N=250001,M=501;
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
e[v].push_back(u);
}
int64 sum;
int n,m,size[N],max[N],cen,cnt[M];
std::bitset<N> f;
void dfs(const int &x,const int &par) {
size[x]=1;
for(unsigned i=0;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs(y,x);
size[x]+=size[y];
max[x]=std::max(max[x],size[y]);
}
max[x]=std::max(max[x],n-size[x]);
if(max[x]<max[cen]) cen=x;
}
void dfs(const int &x,const int &par,const int &dep) {
sum+=dep-1;
for(unsigned i=0;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs(y,x,dep+1);
}
}
int main() {
max[0]=n=getint(),m=sqrt(n);
for(register int i=1;i<n;i++) {
add_edge(getint(),getint());
}
dfs(1,0);
dfs(cen,0,1);
f[0]=true;
for(register unsigned i=0;i<e[cen].size();i++) {
const int &y=e[cen][i];
if(size[y]<=m) {
cnt[size[y]]++;
} else {
f|=f<<size[y];
}
}
for(register int i=1;i<=m;i++) {
for(register int j=1;j<=cnt[i];j<<=1) {
f|=f<<(i*j);
cnt[i]-=j;
}
if(cnt[i]) f|=f<<(i*cnt[i]);
}
int k;
int64 ans=0;
for(k=0;k<=n;k++) {
if(f[k]) ans=std::max(ans,sum+(int64)k*(n-k-1));
}
printf("%d %lld\n",n-1,ans);
return 0;
}

[POI2013]Polaryzacja的更多相关文章

  1. [POI2013]Łuk triumfalny

    [POI2013]Łuk triumfalny 题目大意: 一棵\(n(n\le3\times10^5)\)个结点的树,一开始\(1\)号结点为黑色.\(A\)与\(B\)进行游戏,每次\(B\)能选 ...

  2. [POI2013]Taksówki

    [POI2013]Taksówki 题目大意: ABC三地在同一条直线上,AC相距\(m(m\le10^{18})\)米,AB相距\(d\),B在AC之间.总共有\(n(n\le5\times10^5 ...

  3. [POI2013]Usuwanka

    [POI2013]Usuwanka 题目大意: 一排\(n\)个球,有黑白两种颜色.每取走一个球会在原位置放一个水晶球.求构造一种取球方案,满足: 每次取走\(k\)个白球和\(1\)个黑球: 一次取 ...

  4. [POI2013]Morskie opowieści

    [POI2013]Morskie opowieści 题目大意: 一个\(n(n\le5000)\)点\(m(m\le5000)\)边无向图,边权均为\(1\),有\(k(k\le10^6)\)个询问 ...

  5. [POI2013]Bajtokomputer

    [POI2013]Bajtokomputer 题目大意: 给定一个长度为\(n(n\le10^6)\)的由\(\{-1,0,1\}\)组成的序列,你可以进行\(A_i+=A_{i-1}\)这样的操作, ...

  6. POI2013题解

    POI2013题解 只做了BZ上有的\(13\)道题. 就这样还扔了两道神仙构造和一道计算几何题.所以只剩下十道题了. [BZOJ3414][Poi2013]Inspector 肯定是先二分答案,然后 ...

  7. 【BZOJ3416】Poi2013 Take-out 栈

    [BZOJ3416]Poi2013 Take-out Description 小F喜欢玩一个消除游戏——take-out 保证k+1|n,保证输入数据有解这是一个单人游戏 游戏者的目标是消除初始时给定 ...

  8. 【BZOJ3417】Poi2013 Tales of seafaring 分层图BFS

    [BZOJ3417]Poi2013 Tales of seafaring Description 一个n点m边无向图,边权均为1,有k个询问 每次询问给出(s,t,d),要求回答是否存在一条从s到t的 ...

  9. 【BZOJ3425】Poi2013 Polarization 猜结论+DP

    [BZOJ3425]Poi2013 Polarization Description 给定一棵树,可以对每条边定向成一个有向图,这张有向图的可达点对数为树上有路径从u到达v的点对(u,v)个数.求最小 ...

随机推荐

  1. js调试系列: 初识控制台

    写在最开头:其实我以前就在考虑要不要写这个东西,因为这个东西确实不难,但是为什么会有这么多人问,他们问的不是怎么用控制台,而是不知道控制台能干嘛,他们也知道有 console.log 之类的东西,但他 ...

  2. 格式化 SQL 来提高效率

    本文由 伯乐在线 - cucr 翻译,黄利民 校稿.未经许可,禁止转载!英文出处:msiman.ga.欢迎加入翻译小组. 背景 已格式化的SQL并不比未格式化SQL运行地更快.数据库可能真的不太在意你 ...

  3. MySQL Dual-Master 双向同步

    本文介绍的Mysql Dual-Master 复制实施方法可能不是最完美.最强大的.但是在我的应用环境下能很好的满足各项需求. 本文基于我们仅仅使用两台MySQL服务器的情况下,但是你会发现文章中介绍 ...

  4. 内存对齐与ANSI C中struct型数据的内存布局 【转】

    转自:http://blog.chinaunix.net/uid-25909619-id-3032209.html 当在C中定义了一个结构类型时,它的大小是否等于各字段(field)大小之和?编译器将 ...

  5. c# XML读取

    System.Xml 命名空间 https://msdn.microsoft.com/zh-cn/library/gg145036(v=vs.110).aspx 一.读取 1.通过 XmlDocume ...

  6. MySQL之EXPLAIN 执行计划详解

    explain 可以分析 select 语句的执行,即 MySQL 的“执行计划. 一.type 列 MySQL 在表里找到所需行的方式.包括(由左至右,由最差到最好): | All | index ...

  7. 一个无锁消息队列引发的血案(三)——地:q3.h 与 RingBuffer

    目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...

  8. keyspace notification(键空间通知)-待验证

    一.需求分析: 设置了生存时间的Key,在过期时能不能有所提示? 如果能对过期Key有个监听,如何对过期Key进行一个回调处理? 如何使用 Redis 来实现定时任务? 二.序言: 本文所说的定时任务 ...

  9. Python_oldboy_自动化运维之路_socket编程(十)

    链接:http://www.cnblogs.com/linhaifeng/articles/6129246.html 1.osi七层 引子: 须知一个完整的计算机系统是由硬件.操作系统.应用软件三者组 ...

  10. 【linux】shell中命令替换$(cmd)和符号`cmd`

    来源:https://zhidao.baidu.com/question/485498670.html 作用: $(cmd)和`cmd`的作用是相同的,在执行一条命令时,会先将其中的 ``,或者是$( ...