线性代数(矩阵乘法):NOI 2007 生成树计数



这道题就是深搜矩阵,再快速幂。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
using namespace std;
const int maxn=;
const int mod=;
struct Matrix{
long long mat[maxn][maxn];
int r,c;
Matrix(int r_=,int c_=,int on=){
memset(mat,,sizeof(mat));
r=r_;c=c_;
if(on)for(int i=;i<=r;i++)mat[i][i]=;
}
Matrix operator *(Matrix a){
Matrix ret(r,a.c);
long long l;
for(int i=;i<=r;i++)
for(int k=;k<=c;k++){
l=mat[i][k];
for(int j=;j<=a.c;j++)
(ret.mat[i][j]+=(l*a.mat[k][j])%mod)%=mod;
}
return ret;
}
Matrix operator ^(long long k){
Matrix ret(r,c,),x(r,c);
for(int i=;i<=r;i++)
for(int j=;j<=c;j++)
x.mat[i][j]=mat[i][j];
while(k){
if(k&)
ret=ret*x;
k>>=;
x=x*x;
}
return ret;
}
}A,B; long long n;
map<int,int>ID;
map<int,bool>used;
int k,e,e1,E[maxn][];
int cnt,st[<<],mem[<<];
int fa[maxn],sz[maxn],vis[maxn];
int Find(int x){
return x==fa[x]?x:fa[x]=Find(fa[x]);
}
bool Check(int s){
for(int i=;i<maxn;i++)
fa[i]=i,sz[i]=;
for(int i=;i<e+e1;i++)
if(s&(<<i)){
int u=Find(E[i][]),v=Find(E[i][]);
if(u!=v){fa[u]=v;sz[v]+=sz[u];}
else return false;
}
return true;
} void Solve(int x){
for(int i=;i<=x;i++)
for(int j=i+;j<=x;j++)
E[e][]=i,E[e][]=j,e++;
for(int i=;i<=x;i++)
E[e+e1][]=i,E[e+e1][]=x+,e1++; for(int s=(<<e)-,num;s>=;s--)
if(Check(s)){
memset(vis,,sizeof(vis));num=;
for(int i=;i<=x;i++){
if(vis[Find(i)])continue;
vis[Find(i)]=++num;
}
num=;
for(int i=;i<=x;i++)
num=num*+vis[Find(i)];
if(ID[num])B.mat[ID[num]][]+=;
else{
A.r+=;A.c+=;B.r+=;
B.mat[ID[num]=B.r][]=;
st[++cnt]=s;mem[cnt]=num;
}
} for(int t=,s;t<=cnt;t++){
for(int p=(<<e1)-,num;p>=;p--){
s=st[t]^(p<<e);
if(Check(s)&&sz[Find()]!=){
memset(vis,,sizeof(vis));num=;
for(int i=;i<=x+;i++){
if(vis[Find(i)])continue;
vis[Find(i)]=++num;
}
num=;
for(int i=;i<=x+;i++)
num=num*+vis[Find(i)];
A.mat[ID[num]][ID[mem[t]]]+=;
}
}
}
return;
} int main(){
#ifndef ONLINE_JUDGE
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
#endif
scanf("%d%lld",&k,&n);
k=min(1ll*k,n);Solve(k);B.c=;
A=A^((n-k)%(1ll*(mod+)*(mod-)));B=A*B;
printf("%lld\n",B.mat[][]);
return ;
}
线性代数(矩阵乘法):NOI 2007 生成树计数的更多相关文章
- Codevs 1287 矩阵乘法&&Noi.cn 09:矩阵乘法(矩阵乘法练手题)
1287 矩阵乘法 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 小明最近在为线性代数而头疼, ...
- 【BZOJ 4818】 4818: [Sdoi2017]序列计数 (矩阵乘法、容斥计数)
4818: [Sdoi2017]序列计数 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 560 Solved: 359 Description Al ...
- @总结 - 7@ 生成树计数 —— matrix - tree 定理(矩阵树定理)与 prüfer 序列
目录 @0 - 参考资料@ @0.5 - 你所需要了解的线性代数知识@ @1 - 矩阵树定理主体@ @证明 part - 1@ @证明 part - 2@ @证明 part - 3@ @证明 part ...
- BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法
BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望 ...
- [SDOI2009]HH去散步 「矩阵乘法计数」
计数问题也许可以转化为矩阵乘法形式 比如若该题没有不能在一条边上重复走的条件限制,那么直接将邻接矩阵转化为矩阵乘法即可 故 矩阵乘法计数 对于计数问题,若可以将 \(n\) 个点表示成 \(n \ti ...
- 【BZOJ1494】【NOI2007】生成树计数(动态规划,矩阵快速幂)
[BZOJ1494][NOI2007]生成树计数(动态规划,矩阵快速幂) 题面 Description 最近,小栋在无向连通图的生成树个数计算方面有了惊人的进展,他发现: ·n个结点的环的生成树个数为 ...
- 【BZOJ 4180】 4180: 字符串计数 (SAM+二分+矩阵乘法)
4180: 字符串计数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 164 Solved: 75 Description SD有一名神犇叫做Oxe ...
- 【BZOJ4818】【SDOI2017】序列计数 [矩阵乘法][DP]
序列计数 Time Limit: 30 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Alice想要得到一个长度为n的序 ...
- bzoj1494 生成树计数 (dp+矩阵快速幂)
题面欺诈系列... 因为一个点最多只能连到前k个点,所以只有当前的连续k个点的连通情况是对接下来的求解有用的 那么就可以计算k个点的所有连通情况,dfs以下发现k=5的时候有52种. 我们把它们用类似 ...
随机推荐
- Java NIO 学习笔记
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/3344148.html ...
- HDU 5592 ZYB's Premutation(树状数组+二分)
题意:给一个排列的每个前缀区间的逆序对数,让还原 原序列. 思路:考虑逆序对的意思,对于k = f[i] - f[i -1],就表示在第i个位置前面有k个比当前位置大的数,那么也就是:除了i后面的数字 ...
- <legend>标签
健康信息身高: 体重: 如果表单周围没有边框,说明您的浏览器太老了. <!DOCTYPE HTML> <html> <body> <form> < ...
- C#解leetcode 64. Minimum Path Sum
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...
- TFS 安装与管理
整了几天TFS,把相关的一些配置与安装的要点简单记下,希望对大家有用.本篇主要是安装与配置上的内容,下一篇会介绍如何使用以及使用方面的相关心得体会. 本篇内容简要: 1. 安装部署 1.1. 流 ...
- instanceof的用法①
public class typeof1{ private String a="zzw"; public void instance(){ if(a instanceof Stri ...
- 查询两个日期(时间)以内的数据,between and 或 and 连>= <=,to_date()
between and 方法 select * from kk.kkhmd where larq between(to_date('2008-9-3','yyyy-mm-dd')) and (to_d ...
- MongoDB_1
突然想去看下MongoDB的东西,于是有了这篇文章.其实很早以前就看过一些关于NoSql的文章,还记得当时里面有介绍MongoDB的,多瞅了2眼,并且在Window下安装了MongoDB的驱动,小玩了 ...
- 部分A+B_1
正整数A的“DA(为1位整数)部分”定义为由A中所有DA组成的新整数PA.例如:给定A = 3862767,DA = 6,则A的“6部分”PA是66,因为A中有2个6. 现给定A.DA.B.DB,请编 ...
- 效果类似于label从下往上滑(采用uiTableView实现)
首先附上效果图 进行描述一下:效果就是类似于是一个竖直方向的滚动视图 并且方向是从下往上 并且能够一直这样循环下去. 代码“ // // ViewController.m // demo滚动视图上下 ...