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;
}

LOJ6072苹果树的更多相关文章

  1. codevs 1228 苹果树 树链剖分讲解

    题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...

  2. AC日记——苹果树 codevs 1228

    1228 苹果树  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description 在卡卡的房子外面,有一棵 ...

  3. BZOJ 3757: 苹果树

    3757: 苹果树 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1726  Solved: 550[Submit][Status][Discuss] ...

  4. codevs1228 苹果树

    题目描述 Description 在卡卡的房子外面,有一棵苹果树.每年的春天,树上总会结出很多的苹果.卡卡非常喜欢吃苹果,所以他一直都精心的呵护这棵苹果树.我们知道树是有很多分叉点的,苹果会长在枝条的 ...

  5. 【BZOJ-3757】苹果树 块状树 + 树上莫队

    3757: 苹果树 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1305  Solved: 503[Submit][Status][Discuss] ...

  6. 洛谷P2015 二叉苹果树

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

  7. 【BZOJ】【3757】苹果树

    树分块 orz HZWER http://hzwer.com/5259.html 不知为何我原本写的倍增求LCA给WA了……学习了HZWER的倍增新姿势- 树上分块的转移看vfk博客的讲解吧……(其实 ...

  8. CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划)

    CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划) Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的 ...

  9. 【洛谷2015】【CJOJ1976】二叉苹果树

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

随机推荐

  1. git用法-打补丁【转】

    本文转载自:https://www.cnblogs.com/yandufeng/p/5580765.html 1. git cherry-pick 作用:从一个branch上选择一个commit,添加 ...

  2. openwrt中在软件包中定义PKG_INSTALL将会发生什么?

    答: 将会使用默认软件包安装方式,相关代码如下 . 在include/package.mk中: Build/Install=$(if $(PKG_INSTALL),$(call Build/Insta ...

  3. linux内核中的crng是什么?

    答: 一致性随机数生成器(congruential random number generator)

  4. Java日期时间(Date/Time)

    获取当前日期和时间 在Java中容易得到当前的日期和时间.可以使用一个简单的Date对象的toString()方法,如下所示打印当前日期和时间: import java.util.Date; publ ...

  5. Lintcode452-Remove Linked List Elements-Easy

    Remove Linked List Elements Remove all elements from a linked list of integers that have value val. ...

  6. NOI1999 生日蛋糕

    #include<iostream> #include<cstdio> #include<cmath> using namespace std; #define I ...

  7. HDU 4403 A very hard Aoshu problem(dfs爆搜)

    http://acm.hdu.edu.cn/showproblem.php?pid=4403 题意: 给出一串数字,在里面添加一个等号和多个+号,使得等式成立,问有多少种不同的式子. 思路: 数据量比 ...

  8. React生命周期执行顺序详解

    文章内容转载于https://www.cnblogs.com/faith3/p/9216165.html 一.组件生命周期的执行次数是什么样子的??? 只执行一次: constructor.compo ...

  9. requests:json请求中中文乱码处理

    requests库中,在处理json格式的请求时调用的json.dumps方法参数ensure_ascii默认为True.表示序列化时对中文默认使用的ascii编码.如果想要显示中文,则将此参数的值改 ...

  10. 虹软2.0 免费人脸识别C#类库分享

    目前只封装了人脸检测部分的类库,供大家交流学习,肯定有问题,希望大家在阅读使用的时候及时反馈,谢谢!使用虹软技术开发完成 戳这里下载SDKgithub:https://github.com/dayAn ...