[atARC125F]Tree Degree Subset Sum
令$a_{i}$为$i$的度数-1,那么$(x,s)$合法即等价于存在$S\subseteq [1,n],|S|=x$且$\sum_{k\in S}a_{k}=s$
引理:$(x,s)$合法的必要条件为$-z\le s-x\le z-2$
令$z$为$a_{i}$中为0的元素个数,考虑任意一个集合$S\subseteq [1,n]$,显然$-z\le \sum_{k\in S}a_{k}-|S|\le z-2$
具体的,考虑该式即为$\sum_{k\in S}(a_{k}-1)$,那么将所有$a_{k}<1$的项求和即为最小值,将所有$a_{k}\ge 1$的项求和即为最大值,不难发现前者即为$-z$,后者即为$\sum_{i=1}^{n}a_{i}-(n-z)=z-2$
不难发现,其所描述的即为该引理,也即得证
结论:令$mn(s)=\min_{(x,s)合法}x$和$mx(s)=\max_{(x,s)合法}x$,则$\forall mn(s)\le x\le mx(s),(x,s)$合法
(为了方便,若不存在$(x,s)$合法则定义$mn(s)$和$mx(S)$为$\pm\infty$,显然此时满足结论)
同样令$z$为$a_{i}$中为0的元素个数,显然$mn(s)$对应的方案必然一个0都不选,那么在其基础上再选$[0,z]$个0,即有$\forall mn(s)\le x\le mn(s)+z,(x,s)$合法
类似地,也可以得到$\forall mx(s)-z\le x\le mx(s),(x,s)$合法
由引理即有$mx(s)-mn(s)\le 2z-2$,因此两者区间相交,也即得证
由此,问题即$\forall s$求$mn(s)$和$mx(s)$,这个问题可以dp解决
具体的,(以$mn(s)$为例)令$f_{s}$为对应的答案,则$f_{s}=\min(f_{s},f_{s-a_{i}}+1)$
进一步的,将其对每一种物品(指相同的$a_{i}$)一起处理,假设有$x$个$a_{i}=k$,枚举$s$上选择的$k$个数,即可得到转移为$f_{s}=\min_{0\le i\le x}(f_{s-ik}+i)$,不难用优先队列$o(1)$求出后者
注意到物品种类数至多为$\sqrt{n}$,因此总复杂度为$o(n\sqrt{n})$,可以通过
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 200005 4 #define ll long long 5 int n,x,y,l,r,a[N],tot[N],q[N],mx[N],mn[N],f[N]; 6 ll ans; 7 int main(){ 8 scanf("%d",&n); 9 memset(a,-1,sizeof(a)); 10 for(int i=1;i<n;i++){ 11 scanf("%d%d",&x,&y); 12 a[x]++,a[y]++; 13 } 14 for(int i=1;i<=n;i++)tot[a[i]]++; 15 memset(mn,0x3f,sizeof(mn)); 16 memset(mx,-0x3f,sizeof(mx)); 17 mn[0]=0,mx[0]=tot[0]; 18 for(int i=1;i<=n;i++){ 19 if (!tot[i])continue; 20 for(int j=0;j<i;j++){ 21 l=1,r=0; 22 for(int k=j;k<=n;k+=i){ 23 while ((l<=r)&&(mn[k]-k/i<=mn[q[r]]-q[r]/i))r--; 24 q[++r]=k; 25 while ((l<=r)&&(q[l]/i<k/i-tot[i]))l++; 26 f[k]=mn[q[l]]+(k-q[l])/i; 27 } 28 } 29 memcpy(mn,f,sizeof(f)); 30 } 31 for(int i=1;i<=n;i++){ 32 if (!tot[i])continue; 33 for(int j=0;j<i;j++){ 34 l=1,r=0; 35 for(int k=j;k<=n;k+=i){ 36 while ((l<=r)&&(mx[k]-k/i>=mx[q[r]]-q[r]/i))r--; 37 q[++r]=k; 38 while ((l<=r)&&(q[l]/i<k/i-tot[i]))l++; 39 f[k]=mx[q[l]]+(k-q[l])/i; 40 } 41 } 42 memcpy(mx,f,sizeof(f)); 43 } 44 for(int i=0;i<=n;i++)ans+=max(mx[i]-mn[i]+1,0); 45 printf("%lld\n",ans); 46 return 0; 47 }
原文地址:https://www.cnblogs.com/PYWBKTDA/p/15175427.html
- Java基础-25(02)图形用户界面编程GUI
- 每周算法练习——最近对问题
- Java基础-25(03)图形用户界面编程GUI
- 数据结构和算法——用动态规划求解最短路径问题
- 备库报警邮件的分析案例(一) (r7笔记第14天)
- 数据结构和算法——动态规划
- Java基础-25(05)图形用户界面编程GUI
- Java基础-25(06)图形用户界面编程GUI
- 51. Socket服务端和客户端使用TCP协议通讯 | 厚土Go学习笔记
- 备库报警邮件的分析案例(二) (r7笔记第15天)
- Gotorch - 多机定时任务管理系统
- 备库报警邮件的分析案例(三)(r7笔记第16天)
- 简单易学的机器学习算法——神经网络之BP神经网络
- 24(02)多线程锁,线程通讯,线程组,线程池,多线程三种方式,匿名内部类,定时器,设计模式,单例模式,Runtime
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python爬虫之scrapy的入门使用
- 告别传统工业互联网,提高数字管控思维:三维组态分布式能源站
- 爱奇艺iOS移动端网络优化实践:请求成功率优化
- Java数据类型
- Python爬虫之scrapy构造并发送请求
- Python爬虫之scrapy模拟登陆
- Python爬虫之scrapy中间件的使用
- Python爬虫之scrapy_redis原理分析并实现断点续爬以及分布式爬虫
- Python爬虫之scrapy_splash组件的使用
- Python爬虫之scrapy的日志信息与配置
- Python爬虫之scrapyd部署scrapy项目
- 最近发现一个很有趣的随机小姐姐视频源码 分享给大家
- Codeforces Round #633 (Div. 2)C Powered Addition (贪心,二进制)
- Spring 整合 JUnit
- Java Stax解析XML示例