LOJ6072苹果树
虽然结合了很多算法,但是一步一步地推一下还不算太难的一道题。
首先考虑枚举枚举有用的苹果的集合,然后去算生成树个数。
先考虑怎么计算生成树个数。
发现可以使用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;
}
LOJ6072苹果树的更多相关文章
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
- AC日记——苹果树 codevs 1228
1228 苹果树 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 在卡卡的房子外面,有一棵 ...
- BZOJ 3757: 苹果树
3757: 苹果树 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1726 Solved: 550[Submit][Status][Discuss] ...
- codevs1228 苹果树
题目描述 Description 在卡卡的房子外面,有一棵苹果树.每年的春天,树上总会结出很多的苹果.卡卡非常喜欢吃苹果,所以他一直都精心的呵护这棵苹果树.我们知道树是有很多分叉点的,苹果会长在枝条的 ...
- 【BZOJ-3757】苹果树 块状树 + 树上莫队
3757: 苹果树 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1305 Solved: 503[Submit][Status][Discuss] ...
- 洛谷P2015 二叉苹果树
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...
- 【BZOJ】【3757】苹果树
树分块 orz HZWER http://hzwer.com/5259.html 不知为何我原本写的倍增求LCA给WA了……学习了HZWER的倍增新姿势- 树上分块的转移看vfk博客的讲解吧……(其实 ...
- CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划)
CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划) Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的 ...
- 【洛谷2015】【CJOJ1976】二叉苹果树
题面 Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1.我们用一根树枝两端连 ...
随机推荐
- tp框架中 关于数据库mysql 的一些疑点知识
mysql创建索引, 通常是在 创建表的 同时/时候, 就创建了 即使是在win下, 用命令行操作数据库 , 也要比 图形界面的鼠标操作快得多 索引的类型有: unique, fulltext索引, ...
- [implements] - 一个接口的使用
4种货物,如何使用一个接口实现CRUD: package com.tansuo365.test1.service.goods; import com.tansuo365.test1.entity.Go ...
- go 依赖工具glide
添加gopath/bin目录到环境变量下 安装glide $ go get github.com/Masterminds/glide $ go install github.com/Mastermin ...
- JDBC编程的步骤
一.进行JDBC编程的步骤大致如下: 1. 加载数据库驱动,通常使用Class类的forName()静态方法来加载驱动.如下代码: Class.forName(dirvirClass) 上面 ...
- SAP字段与表的对应关系
SAP字段与表的对应关系 MASTER DATA-主数据 Customer Master KNA1 Customer Basic Data KNB1 ...
- HDU 1403 Longest Common Substring(最长公共子串)
http://acm.hdu.edu.cn/showproblem.php?pid=1403 题意:给出两个字符串,求最长公共子串的长度. 思路: 刚开始学后缀数组,确实感觉很难,但是这东西很强大,所 ...
- css display属性
C:内联元素加上display:block后被块级化.块级元素一般是其他元素的容器,可容纳内联元素和其他块状元素,块级元素排斥其他元素与其位于同一行,width和height起作用.因此,可以定义其宽 ...
- 微信小程序之倒计时插件 wxTimer
微信小程序之倒计时插件 wxTimer 介绍: 用于在微信小程序中进行倒计时的组件. 功能: 1.最基础的当然就是倒计时功能了. 2.可以设置倒计时结束后执行的事件. 3.可以设置倒计时执行过程中 ...
- 每日质量NPM包-classnames
一.classnames 现在到处都追求效率开发,所谓存在即合理,各种各样的开源包/项目火热,也是因为他们大大解决了之前复杂的逻辑.作为榜上前10的热门包:classnames.还真需要了解了解它才能 ...
- 八皇后问题 递归实现 C语言 超详细 思路 基础
八皇后问题 :假设 將八个皇后放到国际象棋盘上,使其两两之间无法相互攻击.共有几种摆法? 基础知识: 国际象棋里,棋盘为8X8格. 皇后每步可以沿直线.斜线 走任意格. 思路: 1.想把8个皇后放进去 ...