51nod1446 Kirchhoff矩阵+Gauss消元+容斥+折半DFS
思路:

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int mod=;
int cases,n,maxval,a[][],C[][],f[],val[],X,g[];
int top2,top,bgn,half,cnts2[],allnum[],Ans,T;
struct Node{int wei,num;Node(){}Node(int x,int y){wei=x,num=y;}}s[+(<<)],s2[+(<<)];
bool operator<(Node a,Node b){return a.wei<b.wei;}
int pow(ll x,int y){
ll res=;
while(y){
if(y&)res=res*x%mod;
x=x*x%mod,y>>=;
}return (int)res;
}
int Gauss(int n){
int f=;
for(int i=;i<=n;i++){
int j=i;while(!a[i][j]&&j<=n)j++;
if(j==n+)return ;
if(j!=i){
for(int k=;k<=n;k++)swap(a[i][k],a[j][k]);
f*=-;
}
int t=pow(a[i][i],mod-);
for(int j=i+;j<=n;j++){
int ww=1ll*a[j][i]*t%mod;
for(int k=i;k<=n;k++)a[j][k]=(a[j][k]-1ll*ww*a[i][k]%mod+mod)%mod;
}
}
ll ans=;
for(int i=;i<=n;i++)ans=ans*a[i][i]%mod;
if(f==-)ans=(mod-ans)%mod;
return ans;
}
void Kirchhoff(int x){
memset(a,,sizeof(a));
for(int i=;i<=n;i++)
if(i<=x)for(int j=max(i+,X+);j<=n;j++)a[i][j]--,a[j][i]--,a[i][i]++,a[j][j]++;
else for(int j=i+;j<=n;j++)a[i][j]--,a[j][i]--,a[i][i]++,a[j][j]++;
}
bool cmp(int x,int y){return x>y;}
void dfs(int x,int wei,int deep){
!T?s[top++]=Node(wei,deep):s2[top2++]=Node(wei,deep);
for(int i=x;i>bgn;i--)if(wei+val[i]<=maxval)dfs(i-,wei+val[i],deep+);
}
signed main(){
for(int i=;i<=;i++){
C[i][]=C[i][i]=;
for(int j=;j<i;j++)C[i][j]=(C[i-][j-]+C[i-][j])%mod;
}
scanf("%d",&cases);
while(cases--){
memset(allnum,,sizeof(allnum));
memset(cnts2,,sizeof(cnts2));
top=top2=X=bgn=Ans=T=;
scanf("%d%d",&n,&maxval);
for(int i=;i<=n;i++){
scanf("%d",&val[i]);
if(~val[i])X++;
}half=(X+)/;
for(int i=;i<=X;i++)Kirchhoff(i),f[i]=g[i]=Gauss(n-);
for(int i=X;~i;i--)
for(int j=i+;j<=X;j++)f[i]=((f[i]-1ll*C[X-i][j-i]*f[j])%mod+mod)%mod;
sort(val+,val++n,cmp),random_shuffle(val+,val++X);
dfs(half,,),sort(s,s+top);
T=,bgn=half,dfs(X,,),sort(s2,s2+top2);
for(int i=;i<top2;i++)cnts2[s2[i].num]++;
for(int i=,j=top2-;i<top;i++){
while(s[i].wei+s2[j].wei>maxval)cnts2[s2[j].num]--,j--;
for(int k=;k<=X-half;k++)(allnum[k+s[i].num]+=cnts2[k])%=mod;
}
for(int i=;i<=X;i++)Ans=(Ans+1ll*f[X-i]*allnum[i])%mod;
printf("%d\n",(Ans+mod)%mod);
}
}
51nod1446 Kirchhoff矩阵+Gauss消元+容斥+折半DFS的更多相关文章
- $Gauss$消元
$Gauss$消元 今天金牌爷来问我一个高消的题目,我才想起来忘了学高消... 高斯消元用于解线性方程组,也就是形如: $\left\{\begin{matrix}a_{11}x_1+a_{12}x_ ...
- 求一个n元一次方程的解,Gauss消元
求一个n元一次方程的解,Gauss消元 const Matrix=require('./Matrix.js') /*Gauss 消元 传入一个矩阵,传出结果 */ function Gauss(mat ...
- Gauss 消元(模板)
/* title:Gauss消元整数解/小数解整数矩阵模板 author:lhk time: 2016.9.11 没学vim的菜鸡自己手打了 */ #include<cstdio> #in ...
- hdu 5755(Gauss 消元) &poj 2947
Gambler Bo Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Tota ...
- 【BZOJ4596】黑暗前的幻想乡(矩阵树定理,容斥)
[BZOJ4596]黑暗前的幻想乡(矩阵树定理,容斥) 题面 BZOJ 有\(n\)个点,要求连出一棵生成树, 指定了一些边可以染成某种颜色,一共\(n-1\)种颜色, 求所有颜色都出现过的生成树方案 ...
- poj 1681(Gauss 消元)
Painter's Problem Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5875 Accepted: 2825 ...
- POJ 1830 开关问题(Gauss 消元)
开关问题 Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 7726 Accepted: 3032 Description ...
- bzoj4596/luoguP4336 [SHOI2016]黑暗前的幻想乡(矩阵树定理,容斥)
bzoj4596/luoguP4336 [SHOI2016]黑暗前的幻想乡(矩阵树定理,容斥) bzoj Luogu 题解时间 看一看数据范围,求生成树个数毫无疑问直接上矩阵树定理. 但是要求每条边都 ...
- loj#6072 苹果树(折半搜索,矩阵树定理,容斥)
loj#6072 苹果树(折半搜索,矩阵树定理,容斥) loj 题解时间 $ n \le 40 $ . 无比精确的数字. 很明显只要一个方案不超过 $ limits $ ,之后的计算就跟选哪个没关系了 ...
随机推荐
- 深入理解PHP之foreach
招聘 标签(空格分隔): 招聘 PHP 国贸 语言基础 foreach 语法结构提供了遍历数组的简单方式. php5之前, foreach仅能用于数组php5+, 利用foreach可以遍历对象 fo ...
- buf.write()
buf.write(string[, offset[, length]][, encoding]) string {String} 需要被写入到 Buffer 的字节 offset {Number} ...
- 51NOD 1385凑数字(找规律?)
>>点击进入原题测试<< 思路:这个题是真的想了蛮久,枚举了一下前一百就发现了规律,要想最短的话就是要构建1234567890这个字符串:刚开始找到的规律从1开始枚举到N,每满 ...
- hihocoder 1032 最长回文子串(Manacher)
传送门 #include<queue> #include<cmath> #include<cstdio> #include<cstring> #incl ...
- 【Codeforces 369C】 Valera and Elections
[链接] 我是链接,点我呀:) [题意] 给你一棵树 让你选择若干个修理点. 这些修理点被选中之后,节点i到1号节点之间的所有"坏路"都会被修好 问最少需要选择多少个点才能将所有的 ...
- CodeForces 220B(B. Little Elephant and Array)
http://codeforces.com/contest/220/problem/B 题意:给出一个数组,给出m组询问,问区间中出现a[i] 次的有多少个. sl: 很显然的离线问题了. 大视野菜花 ...
- 转载 - Struts2 拦截器详细配置过程
出处:http://www.blogjava.net/zzzlyr/archive/2009/10/12/297998.html Struts2 拦截器详细配置过程 1:所有拦截器的超级接口Inter ...
- 利用async和await异步操作解决node.js里面fs模块异步读写,同步结果的问题
async await 解决异步问题,这两个关键字是es7提出的,所以测试,node和浏览器版本提高一些 async await 操作基于promise实现的 async await这两个关键字是一起 ...
- 20181010关于pt-kill自动杀死运行超长的进程
转自: http://blog.chinaunix.net/uid-16844903-id-4442030.htmlhttp://blog.chinaunix.net/uid-31396856-id- ...
- Win32编程API 基础篇 -- 3.消息处理 根据英文教程翻译
消息处理 例子:窗口点击 好的,现在我们已经得到一个窗口了,但我们什么也做不了除了DefWindowProc()允许窗口大小被调整,最大最小化等...这不是很激动人心啊 在接下来的一小节中我将向你展示 ...