[NOI2007]生成树计数 (基于连通性的状态压缩动态规划+矩阵快速幂优化)

题意:n个点排成一排,每个点往它前k个点连边,求生成树个数。
n &lt; = 1 e 15 , k &lt; = 5 n&lt;=1e15,k&lt;=5 n<=1e15,k<=5
其实这个题很OI的。
考虑从左到右把点加入然后维护生成树个数,可以发现需要区分的状态只有前k的点的联通情况(快速判断成环或不连通),然后最小表示法基于连通性的状态压缩dp一发,然后就是喜闻乐见的发现状态数很少但转移次数很多,可以使用矩阵乘法其实我觉得怎么不求特征多项式然后来一发常系数线性递推呢?
原来没有插头就不用特别考虑0的情况啊。。。。。。
原来n<=k的时候可以用n(n-2)啊。。。。。。
原来按照本能把i->j的转移方案数放在a[i][j]的时候矩阵的柿子是右乘转移啊。。。。。。
原来对于n个点的联通情况用最小表示法只有 B e l l ( n ) Bell(n) Bell(n)种啊(Bell(5)=52,Bell(6)=203,Bell(7)=877,Bell(8)=4140,Bell(9)=21147,Bell(10)=115975)

#include<bits/stdc++.h>
#define LL long long
#define mod 65521 
using namespace std;

LL n;
int k,id[100000],pos[300],cnt,mask[15],lt[15];

struct mat
{
   
	int a[210][210];
	mat(int d=0){
   memset(a,0,sizeof a);for(int i=1;i<=cnt;i++) a[i][i]=d;};
	mat operator *(const mat &B)const
	{
   
		mat ret=mat(0);
		for(int i=1;i<=cnt;i++)
			for(int j=1;j<=cnt;j++) if(a
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值