【LOJ#6072】苹果树(矩阵树定理,折半搜索,容斥)
【LOJ#6072】苹果树(矩阵树定理,折半搜索,容斥)
题面
LOJ
题解
emmmm,这题似乎猫讲过一次。。。
显然先\(meet-in-the-middle\)搜索一下对于每个有用的苹果数量,满足权值小于\(lim\)的方案数
,那么只需要考虑它们构成生成树的方案数就好了。
显然有用的可以和所有的有用的或者是坏的连边,好的但不有用的只能和坏的连边,而坏的随意。
但是这样子算出来的结果是至多,因此还需要额外容斥一下计算生成树的个数。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAX 50
#define MOD 1000000007
void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
inline int read()
{int x=0;bool t=false;char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-')t=true,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return t?-x:x;
}
int n,limit,m,c[MAX];
struct Node{int S,d;}S1[1050000],S2[1050000];
bool operator<(Node a,Node b){return a.S<b.S;}
int top1,top2;
void dfs1(int x,int S,int D)
{if(S>limit)return;if(x==m+1){S1[++top1]=(Node){S,D};return;}dfs1(x+1,S,D);if(c[x]>-1)dfs1(x+1,S+c[x],D+1);
}
void dfs2(int x,int S,int D)
{if(S>limit)return;if(x==n+1){S2[++top2]=(Node){S,D};return;}dfs2(x+1,S,D);if(c[x]>-1)dfs2(x+1,S+c[x],D+1);
}
int Cnt[MAX],cc[MAX];
int Sum[MAX],tot;
int a[MAX][MAX],C[MAX][MAX];
int fpow(int a,int b)
{int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;
}
void link(int x,int y){++a[x][x],++a[y][y];--a[x][y],--a[y][x];}
int Matrix_Tree(int k)
{for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)a[i][j]=0;for(int i=1;i<=n;++i)for(int j=i+1;j<=n;++j)if(i<=k){if(j<=k||j>tot)link(i,j);}else if(i>tot)link(i,j);else if(j>tot)link(i,j);for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)a[i][j]=(a[i][j]+MOD)%MOD;int ans=1;for(int i=1;i<n;++i){for(int j=i+1;j<n;++j){int t=1ll*a[j][i]*fpow(a[i][i],MOD-2)%MOD;for(int k=i;k<n;++k)a[j][k]=(a[j][k]+MOD-1ll*t*a[i][k]%MOD)%MOD;}ans=1ll*ans*a[i][i]%MOD;}return ans;
}
int main()
{n=read();limit=read();m=(n+1)/2;for(int i=1;i<=n;++i)c[i]=read();for(int i=1;i<=n;++i)tot+=(c[i]!=-1);dfs1(1,0,0);dfs2(m+1,0,0);sort(&S1[1],&S1[top1+1]);sort(&S2[1],&S2[top2+1]);for(int i=top1,j=1;i;--i){while(j<=top2&&S1[i].S+S2[j].S<=limit)cc[S2[j].d]+=1,++j;for(int k=0;k<=n;++k)add(Cnt[S1[i].d+k],cc[k]);}for(int i=0;i<=n;++i)C[i][0]=1;for(int i=1;i<=n;++i)for(int j=1;j<=i;++j)C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;for(int i=0;i<=tot;++i)Sum[i]=Matrix_Tree(i);for(int i=1;i<=tot;++i)for(int j=0;j<i;++j)Sum[i]=(Sum[i]+MOD-1ll*C[i][j]*Sum[j]%MOD)%MOD;int ans=0;for(int i=0;i<=tot;++i)add(ans,1ll*Cnt[i]*Sum[i]%MOD);printf("%d\n",ans);return 0;
}
转载于:https://www.cnblogs.com/cjyyb/p/10211311.html
【LOJ#6072】苹果树(矩阵树定理,折半搜索,容斥)相关推荐
- BZOJ1016 || 洛谷P4208 [JSOI2008]最小生成树计数【矩阵树定理】
时空限制 1000ms / 128MB 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则 ...
- 矩阵树定理2020HDU多校第6场j-Expectation[位运算+期望]
矩阵树定理 用于求解图上面生成树的个数,生成树的个数等于基尔霍夫矩阵的任何一个N-1阶主子式的行列式的绝对值 矩阵树模板 struct Matrix_Tree {ll a[N][N];Matrix_T ...
- Luogu P4336 [SHOI2016]黑暗前的幻想乡(容斥,矩阵树定理,子集反演)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Luogu P4336 [SHOI2016]黑暗前的幻想乡(容斥,矩阵树定理) Problem n≤1 ...
- 【学习笔记】矩阵树定理(Matrix-Tree)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 一.矩阵树定理 二.常用定理 三.例题 1. Luogu P6178 [模板]Matrix-Tr ...
- 图论数学:矩阵树定理
运用矩阵树定理进行生成树计数 给定一个n个点m条边的无向图,问生成树有多少种可能 直接套用矩阵树定理计算即可 矩阵树定理的描述如下: 首先读入无向图的邻接矩阵,u-v G[u][v]++ G[v][u ...
- [CF917D]Stranger Trees[矩阵树定理+解线性方程组]
题意 给你 \(n\) 个点的无向完全图,指定一棵树 \(S\),问有多少棵生成树和这棵树的公共边数量为 \(k\in[0,n-1]\) \(n\leq 100\) 分析 考虑矩阵树定理,把对应的树边 ...
- HDU多校6 - 6836 Expectation(矩阵树定理+高斯消元求行列式)
题目链接:点击查看 题目大意:给出一张由 n 个点和 m 条边组成的无向图,对于任意一个生成树,其权值为 n - 1 条边的边权进行二进制的 and 运算,现在需要在图中任意选择一个生成树,问期望权值 ...
- Wannafly挑战赛23F-计数【原根,矩阵树定理,拉格朗日插值】
正题 题目链接:https://ac.nowcoder.com/acm/contest/161/F 题目大意 给出nnn个点的一张图,求它的所有生成树中权值和为kkk的倍数的个数.输出答案对ppp取模 ...
- P3317-[SDOI2014]重建【矩阵树定理,数学期望】
正题 题目链接:https://www.luogu.com.cn/problem/P3317 题目大意 nnn个点若干条边.告诉你每条边出现的概率,求刚好出现一颗生成树的概率是多少. 解题思路 矩阵树 ...
最新文章
- (转贴)给Repeater、Datalist和Datagrid增加自动编号列
- mybatis 使用in 查询时报错_使用mybatis的resultMap进行复杂查询 057
- 2018.10.17考试
- CIO时代客户交流会,强强联合共筑电子政务美好未来
- HIve学习:Hive分区修改
- Linux文件查找之findlocate
- 22岁少年破解史上最严重网络攻击,拯救全球互联网,三个月后却被FBI逮捕
- python程序如何做界面_如何用Python给已有小程序做界面?
- Linux开机启动过程(5):内核解压
- python unicode转字符串_Python2.X如何将Unicode中文字符串转换成 string字符串
- 简单的eda实验vga在linux系统中,《EDA实验报告VGA彩条显示.doc
- 转:error LNK2001 错误
- Grafana教程(prometheus 基本查询语法,alerting报警)
- 我爱刷题系列汇总(51-100)【2017.11.24-2018.01.12】
- 面经 | 靠一份PPT做自我介绍,成功拿下了互联网名企offer
- AMD GPU 系列版本信息
- MIPI 打怪升级之DSI篇
- 央行征信与互联网征信技术接口区别(征信架构篇)
- 误入 GitHub 游戏区,结果意外地收获颇丰
- vsync, hsync, VBLANK