BZOJ.3425.[POI2013]Polarization(DP 多重背包 二进制优化)
最小可到达点对数自然是把一条路径上的边不断反向,也就是黑白染色后都由黑点指向白点。这样答案就是\(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 多重背包 二进制优化)的更多相关文章
- HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)
HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...
- HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)
HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...
- HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化)
HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化) 题意分析 首先C表示测试数据的组数,然后给出经费的金额和大米的种类.接着是每袋大米的 ...
- hdu1059 dp(多重背包二进制优化)
hdu1059 题意,现在有价值为1.2.3.4.5.6的石头若干块,块数已知,问能否将这些石头分成两堆,且两堆价值相等. 很显然,愚蠢的我一开始并想不到什么多重背包二进制优化```因为我连听都没有听 ...
- 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 ...
- hdu 2191 (多重背包+二进制优化)
Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品, ...
- Coins(多重背包+二进制优化)
Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...
- Cash Machine POJ - 1276 多重背包二进制优化
题意:多重背包模型 n种物品 每个m个 问背包容量下最多拿多少 这里要用二进制优化不然会超时 #include<iostream> #include<cstdio> #in ...
- HDU 5445 Food Problem(多重背包+二进制优化)
http://acm.hdu.edu.cn/showproblem.php?pid=5445 题意:现在你要为运动会提供食物,总共需要提供P能量的食物,现在有n种食物,每种食物能提供 t 能量,体积为 ...
随机推荐
- 【Python】批量查询-提取站长之家IP批量查询的结果加强版本v3.0
1.工具说明 写报告的时候为了细致性,要把IP地址对应的地区给整理出来.500多条IP地址找出对应地区复制粘贴到报告里整了一个上午. 为了下次更好的完成这项重复性很高的工作,所以写了这个小的脚本. 某 ...
- UML和模式应用5:细化阶段(10)---UML交互图
1.前言 UML使用交互图来描述对象间消息的交互 交互图可以用于动态对象建模. 交互图有两种类型:顺序图和通信图. UML交互图将用来解释和阐述对象设计. 2.顺序图和通信图 顺序图具有丰富的符号标记 ...
- eclipse引入系统类库
引入系统类库1.第一步:项目,右键,build path,remove报错的类库 2.第二步:项目,右键,build path→Add Library→JRE System Library,Next3 ...
- 编译时bad substitution的解决办法
由于使用的使用的编译器不同导致, 需要使用shell为 #!/bin/bash 即可.
- Android用户界面开发:TabHost
TabHost是整个Tab的容器,包括两部分,TabWidget和FrameLayout.TabWidget就是每个tab的标签,FrameLayout则是tab内容.TabHost的二种实现方式:第 ...
- Ex 6_18 硬币有限的兑换问题_第七次作业
子问题定义: 定义一个二维数组b,其中b[i][j]表示前i个币种是否能兑换价格j,表示第i个币种的面值,第i个币种的使用有两种情况,若使用,则b[i][j]=b[i-1][j-],若不使用,则b[i ...
- Node.js Error: listen EADDRNOTAVAIL
1 前言 nodejs部署在云服务器,外网用域名加端口访问不进来,但在服务器本地用127.0.0.1加端口可以访问,并且端口已经放开,然后只能排查配置.此文章仅作为记录使用. 如果端口和另一个的端口一 ...
- js实现星级评分效果(非常规5个li代码)
1. 前言 此方案受到JS单行写一个评级组件启发,自己写了一个简单Demo. 功能有正常滑动,动态显示实心星星个数:当点击确认,则保持当前的实心星星个数:再移动时未点击,则离开后还是保持之前的状态. ...
- centos 报错 “Job for iptables.service failed because the control process exited with error code.”的解决办法
原因:因为centos7默认的防火墙是firewalld防火墙,不是使用iptables,因此需要先关闭firewalld服务,或者干脆使用默认的firewalld防火墙. 操作步骤: 关闭防火墙 1 ...
- Python-JS事件与面向对象操作
目录一.函数高级 循环绑定: 使用循环绑定会出现的问题及解决方案: 二.面向对象 3.构造函数(ES5) 三.JS选择器 1.getElement系列(最严谨) 2.querySelector系列(最 ...