https://loj.ac/problem/6072

虽然结合了很多算法,但是一步一步地推一下还不算太难的一道题。

首先考虑枚举枚举有用的苹果的集合,然后去算生成树个数。

先考虑怎么计算生成树个数。

发现可以使用matrix-tree。

所有有用点可以和有用点以及坏点连边,所有不是坏点的无用点只能和坏点连边,坏点可以和所有点连边。

然后跑一下matrix-tree。但是这样算出来的是至多S这个集合为有用点的方案数,需要套一个容斥。

分析上述过程,发现需要的信息只有好点的个数。

因此可以只需要计算出大小为k的和<lim合法集合有多少即可,这个显然可以meet in the middle。

#include<bits/stdc++.h>
#define N 44
#define M 1100000
#define ll long long
using namespace std;
inline int read()
{char ch=0;int x=0,flag=1;while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}return x*flag;
}
const int mo=1e9+7;
int ksm(int x,int k)
{int ans=1;while(k){if(k&1)ans=1ll*ans*x%mo;k>>=1;x=1ll*x*x%mo;}return ans;
}
int inv(int x){return ksm((x%mo+mo)%mo,mo-2);}
int a[N][N];
int matrix_tree(int n)
{int ans=1;for(int i=1;i<=n;i++)if(!a[i][i])return 0;for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){int t=1ll*a[j][i]*inv(a[i][i])%mo;for(int k=i;k<=n;k++)a[j][k]=(a[j][k]-(1ll*t*a[i][k]%mo))%mo;}ans=1ll*ans*a[i][i]%mo;}return (ans%mo+mo)%mo;
}
int w[N],sz[N],dp[N],ans[N],c[N][N],f[N/2][M];
bool cmp(int a,int b){return a>b;}
int main()
{int n=read(),lim=read(),cnt=0,res=0;for(int i=1;i<=n;i++)w[i]=read(),cnt+=(w[i]==-1);sort(w+1,w+n+1,cmp);int m=n-cnt,mid=m/2;for(int s=0;s<(1<<mid);s++){int num=0,tot=0;for(int i=1;i<=mid;i++)if(1<<(i-1)&s)num++,tot+=w[i];if(tot<=lim)f[num][++sz[num]]=tot;}for(int i=0;i<=mid;i++)sort(f[i]+1,f[i]+sz[i]+1);for(int s=0;s<(1<<(m-mid));s++){int num=0,tot=0;for(int i=1;i<=m-mid;i++)if(1<<(i-1)&s)num++,tot+=w[i+mid];for(int i=0;i<=mid;i++)dp[i+num]=(dp[i+num]+(upper_bound(f[i]+1,f[i]+sz[i]+1,lim-tot)-f[i]-1))%mo;}for(int i=0;i<=n;i++){c[i][0]=1;for(int j=1;j<=n;j++)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mo;}for(int o=0;o<=m;o++){for(int i=1;i<=o;i++)for(int j=1;j<=n;j++)if(i==j)a[i][j]=(o-1)+cnt;else a[i][j]=-(j<=o||j>m);for(int i=o+1;i<=m;i++)for(int j=1;j<=n;j++)if(i==j)a[i][j]=cnt;else a[i][j]=-(j>m);for(int i=m+1;i<=n;i++)for(int j=1;j<=n;j++)if(i==j)a[i][j]=n-1;else a[i][j]=-1;ans[o]=matrix_tree(n-1);for(int i=0;i<o;i++)ans[o]=(ans[o]-(1ll*c[o][i]*ans[i]%mo))%mo;res=(res+(1ll*dp[o]*ans[o]%mo))%mo;}printf("%d",(res%mo+mo)%mo);return 0;
}

转载于:https://www.cnblogs.com/Creed-qwq/p/10641579.html

LOJ6072苹果树相关推荐

  1. 【LOJ6072】苹果树【折半搜索】【矩阵树定理】【二项式反演】

    题意:有好坏两种点共 nnn 个,每个好点有权值,把这 nnn 个点连成一棵树,一个好点为有用的当且仅当它至少与一个好点相邻,求所有有用的点的权值和不超过 limlimlim 的方案数. n≤40n\ ...

  2. P2015 二叉苹果树

    传送门 这道题要用到链式前向星... 非常标准的树形背包DP 只要理解了,题就不难 只要理解了...... 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树 ...

  3. 苹果树的故事(转发的)

    一棵苹果树,终于结果了. 第一年,它结了十个苹果,九个被拿走,自己得到一个.对此,苹果树愤愤不平,于是自断经脉,拒绝成长.第二年,它结了五个苹果,四个被拿走,自己得到一个."哈哈,去年我得到 ...

  4. 洛谷 P2015 二叉苹果树

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...

  5. 二叉苹果树(树型DP+背包)

    二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点).这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号 ...

  6. JZOJ 1016. 【PKU3321】苹果树

    Description 你家门前种了一棵苹果树,每年秋天,树上都结满了苹果,你非常喜欢吃苹果,所以一直精心照料着苹果树. 苹果树有N个分叉,分叉之间由枝干相连,你把分叉用1到N来标记,树根必须记为1. ...

  7. 洛谷2015 二叉苹果树 树形DP

    https://www.luogu.org/problemnew/show/P2015 二叉苹果树 时间限制: 1 Sec  内存限制: 128 MB 题目描述 有一棵苹果树,如果树枝有分叉,一定是分 ...

  8. 苹果树(线段树+Dfs序)

    1228 苹果树  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 在卡卡的房子外面,有一棵苹果树.每年的春天,树上总会结 ...

  9. 兰州大学第一届 飞马杯 ★★快乐苹果树★★ 树链剖分 + 懒标记 + 树状数组

    传送门 文章目录 题意: 思路: 题意: 思路: 第一次听说树链剖分能在fa[top[i]]fa[top[i]]fa[top[i]]的地方加懒标记,学到了学到了. 首先不能被题目吓住,这个题目仔细剖析 ...

最新文章

  1. php imagecopy 用法,php使用imagecopymerge()函数创建半透明水印
  2. 001_Gson概述
  3. ArcObjects中的几何对象简介(一)
  4. 递归行为时间复杂度估算
  5. 【云上ELK系列】Logstash迁移Elasticsearch数据方法解读
  6. 一篇讲清:如何构建可重复,可扩展且盈利的“魔力”转化流程?
  7. 了解jQuery并掌握jQuery对象和DOM对象的区别
  8. linux内核的冒险md来源释义# 14raid5非条块读
  9. python怎么绘制渐变图_用Python画colorbar渐变图+修改刻度大小+修改渐变颜色
  10. 我国四大常用坐标系及高程坐标系【转载】
  11. 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字(简单易懂)
  12. step14. ubuntu18.04下载安装scala(转)
  13. 在CentOS 7 1804 中 安装 使用 GitLab 11.4.3-ee (企业版、社区版最新版、或任意版本)
  14. 同花顺显示正在切换服务器,同花顺服务器架构
  15. ros平台下python脚本控制机械臂运动
  16. 服务器系统盘如何克隆,如果把云服务器系统盘克隆
  17. CAD关闭图层快捷键,隐藏显示的CAD图层
  18. 弯下腰,只为一个昂起头的机会
  19. A Survey of Recent Development in Indoor Visible Light Positioning
  20. udo/tcp协议占用端口列表(因5060被占用而采用的新端口)

热门文章

  1. 百度理财产品将或是余额宝的克星?
  2. MySQL使用SQL语句新增字段、删除字段
  3. js根据数组长度生成新数组
  4. uva 10586 - Polynomial Remains(数论)
  5. 娱乐项目 | 直播看电影还能赚钱?
  6. xls文件操作,中文模糊匹配
  7. java时间戳的比较_Java时间戳比较
  8. 抽样分布:经常听到的卡方分布、t分布等的含义是啥?
  9. 解决iframe跨域问题
  10. vscode使用远程服务器jupyter