BZOJ

洛谷

最小可到达点对数自然是把一条路径上的边不断反向,也就是黑白染色后都由黑点指向白点。这样答案就是\(n-1\)。

最大可到达点对数,容易想到找一个点\(a\),然后将其子树分为两部分\(x,y\),\(x\)子树所有边全指向\(a\),\(a\)与\(y\)子树之间的边全指向\(y\)。这样答案就是\(sz[x]\times sz[y]\),要让\(sz[x],sz[y]\)尽量相等。找重心就好了。

然后DP,求划分重心两部分子树大小分别为\(x\)和\(n-1-x\)是否可行。

\(f[i]\)表示一部分子树\(sz\)和为\(i\)是否可行。转移就是个可行性背包,可以用\(bitset\)优化到\(\frac{n^2}{w}\),但还是不够。

对于\(size\geq\sqrt{n}\)的子树,最多不会超过\(\sqrt{n}\)个,可以直接背包转移。

对于\(size<\sqrt{n}\)的子树,根据\(size\)按多重背包做,可以直接二进制拆分。

复杂度为\(O(\frac{n\sqrt{n}\log n}{w})\)。

注意到\(\sum sz[i]=n\),所以\(sz[i]\)最多有\(O(\sqrt{n})\)种(\(1+2+...+\sqrt{n}\approx n\))。

即这是一个有\(O(\sqrt{n})\)个物品的多重背包。用二进制拆分有\(O(\sqrt{n}\log n)\)个物品。

二进制优化,从小到大,有一个物品\(x\)出现超过两次,就把两个合并成一个给\(2x\)。这样物品总数就是\(O(\sqrt{n})\)了。

所以复杂度为\(O(\frac{n\sqrt{n}}{w})\)。(虽然实际比上面的做法还慢一点儿==)

当根节点度数大于\(\sqrt{n}\)时可以用堆做:https://blog.csdn.net/neither_nor/article/details/52725690。大体看了看15年论文没看见这个做法 不细看了

//13704kb	3020ms(13572kb	3216ms)
#include <cmath>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=250005; int n,Enum,H[N],nxt[N<<1],to[N<<1],sz[N],root,Max,cnt[N];
std::bitset<N> f; 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 void AE(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 Get_root(int x,int f)
{
int mx=0; sz[x]=1;
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=f)
{
Get_root(v,x), sz[x]+=sz[v];
if(sz[v]>mx) mx=sz[v];
}
mx=std::max(mx,n-sz[x]);
if(mx<Max) Max=mx, root=x;
}
void DFS(int x,int f)
{
sz[x]=1;//重算一遍sz啊 想什么呢
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=f) DFS(v,x), sz[x]+=sz[v];
} int main()
{
n=read();
for(int i=1; i<n; ++i) AE(read(),read());
Max=1e9, Get_root(1,1), DFS(root,0); // f[0]=1;//O(n*sqrt(n)/w)
// for(int i=H[root]; i; i=nxt[i]) ++cnt[sz[to[i]]];
// for(int i=1; i<=n; ++i)
// if(cnt[i]>2) cnt[i<<1]+=(cnt[i]-1)>>1, cnt[i]=1+!(cnt[i]&1);
// for(int i=1; i<=n; ++i)
// while(cnt[i]--) f|=f<<i; f[0]=1; const int lim=sqrt(n);//O(n*sqrt(n)*logn/w)
for(int i=H[root]; i; i=nxt[i])
if(sz[to[i]]<lim) ++cnt[sz[to[i]]];
else f|=f<<sz[to[i]];
for(int i=1; i<lim; ++i)
for(int j=cnt[i],k=1; j; j-=k,k<<=1)
if(j>k) f|=f<<i*k;
else {f|=f<<i*j; break;} LL ans=0;
for(int i=1; i<n; ++i) if(f[i]) ans=std::max(ans,1ll*i*(n-1-i));
for(int i=1; i<=n; ++i) ans+=sz[i];
printf("%d %lld\n",n-1,ans-n); return 0;
}

BZOJ.3425.[POI2013]Polarization(DP 多重背包 二进制优化)的更多相关文章

  1. HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)

    HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...

  2. HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)

    HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...

  3. HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化)

    HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化) 题意分析 首先C表示测试数据的组数,然后给出经费的金额和大米的种类.接着是每袋大米的 ...

  4. hdu1059 dp(多重背包二进制优化)

    hdu1059 题意,现在有价值为1.2.3.4.5.6的石头若干块,块数已知,问能否将这些石头分成两堆,且两堆价值相等. 很显然,愚蠢的我一开始并想不到什么多重背包二进制优化```因为我连听都没有听 ...

  5. HDU 1171 Big Event in HDU 多重背包二进制优化

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1171 Big Event in HDU Time Limit: 10000/5000 MS (Jav ...

  6. hdu 2191 (多重背包+二进制优化)

    Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品, ...

  7. Coins(多重背包+二进制优化)

    Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...

  8. Cash Machine POJ - 1276 多重背包二进制优化

    题意:多重背包模型  n种物品 每个m个  问背包容量下最多拿多少 这里要用二进制优化不然会超时 #include<iostream> #include<cstdio> #in ...

  9. HDU 5445 Food Problem(多重背包+二进制优化)

    http://acm.hdu.edu.cn/showproblem.php?pid=5445 题意:现在你要为运动会提供食物,总共需要提供P能量的食物,现在有n种食物,每种食物能提供 t 能量,体积为 ...

随机推荐

  1. 【Mysql sql inject】【入门篇】SQLi-Labs使用 part 1【01-11】

    人员流动性过大一直是乙方公司痛点.虽然试用期间都有岗前学习,但老员工忙于项目无暇带新人成长,入职新人的学习基本靠自己不断摸索.期望看相关文档就可以一蹴而是不现实的.而按部就班的学习又很难短期内将知识有 ...

  2. 【转】Shell编程基础篇-下

    [转]Shell编程基础篇-下 1.1 条件表达式 1.1.1 文件判断 常用文件测试操作符 常用文件测试操作符 说明 -d文件,d的全拼为directory 文件存在且为目录则为真,即测试表达式成立 ...

  3. python高级编程读书笔记(一)

    python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...

  4. elk系统通过nginx添加对kibana的登录认证

    elk系统添加对kibana的登录认证 关于elk系统的安装配置可以参考:Centos6.5安装Logstash ELK stack 日志管理系统及使用详解 http://blog.csdn.net/ ...

  5. Expm 8_1 区间划分问题

      [问题描述] 给定一组报告,其中的每个报告设置了一个开始时间si和结束时间fi.设计与实现一个算法,对这组报告分配最少数量的教室,使得这些报告能无冲突的举行. package org.xiu68. ...

  6. spring使用JdbcTemplate和jdbcDaosupport及具名参数使用

    关于jdbctemplate: 个人感觉比Java链接mysql那一套方便好维护多了,只需在配置文件维护即可 需要的包: com.springsource.net.sf.cglib-2.2.0.jar ...

  7. P3660 【[USACO17FEB]Why Did the Cow Cross the Road III G】

    题外话:维护区间交集子集的小套路 开两个树状数组,一个维护进入区间,一个维护退出区间 $Query:$ 给定询问区间$l,r$和一些其他区间,求其他区间中与$[l,r]$交集非空的区间个数 用上面维护 ...

  8. linux下安装ruby环境

    安装步骤: ruby的shell叫irb,我们可以输入irb -v查看下irb的版本号 1.安装ruby解释器shell: yum install ruby-irb -y Installed: rub ...

  9. Java_myeclipse添加DTD约束(框架xml只能提示功能)

    以struts2中的xml为例 struts-2.3.4-all\struts-2.3.4\src\core\src\main\resources

  10. JS高级 - 面向对象2(prototype定义)

    定义和用法 prototype 属性允许您向对象添加属性和方法 注意: Prototype 是全局属性,适用于所有的Javascript对象. 语法 object.prototype.name=val ...