http://acm.hdu.edu.cn/showproblem.php?pid=5411
无限超时,测评机抖一抖过了...
卡取模时间,可以等累加起来后再一起取模。
题目大意,就是有n个模块,然后给出一些模块是可以组合,问你组合一个组合两个...最多组合m个,方法数合。
下面有两种矩阵快速幂的乘法形式,应该根据实际情况选取。
ju jumul(ju a,ju b)
{//矩阵乘法
int i,j,k;
ju c;
c.CSH();
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(a.a[i][j])
for(k=0;k<n;k++)
c.a[i][k]=(c.a[i][k]+a.a[i][j]*b.a[j][k])%mod;
return c;
}
<p style="margin-top: 0px; margin-bottom: 0px; font-size: 16px; font-family: Menlo; color: rgb(115, 253, 255);">
</p>第二种:
ju jumul(ju a,ju b)
{//矩阵乘法
int i,j,k;
ju c;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
c.a[i][j]=0;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
for(k=0;k<n;k++)
c.a[i][j]+=a.a[i][k]*b.a[k][j];
c.a[i][j]%=mod;
}
}
return c ;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
inline int read()
{
char ch;
bool flag = false;
int a = 0;
while(!((((ch = getchar()) >= '0') && (ch <= '9')) || (ch == '-')));
if(ch != '-')
{
a *= 10;
a += ch - '0';
}
else
{
flag = true;
}
while(((ch = getchar()) >= '0') && (ch <= '9'))
{
a *= 10;
a += ch - '0';
}
if(flag)
{
a = -a;
}
return a;
}
void write(int a)
{
if(a < 0)
{
putchar('-');
a = -a;
}
if(a >= 10)
{
write(a / 10);
}
putchar(a % 10 + '0');
}
const int mod=2015;
const int maxn=52;
int n,m;
struct ju
{//矩阵
int a[maxn][maxn];
void init()
{//初始化
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
a[i][j]=0;
for(int i=0;i<n;i++ )
a[i][i]=1;
}
};
ju juadd(ju a,ju b)
{//矩阵加法
int i,j;
ju c;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
c.a[i][j]=((a.a[i][j]+b.a[i][j])%mod);
return c;
}
ju jumul(ju a,ju b)
{//矩阵乘法
int i,j,k;
ju c;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
c.a[i][j]=0;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
for(k=0;k<n;k++)
c.a[i][j]+=a.a[i][k]*b.a[k][j];
c.a[i][j]%=mod;
}
}
return c ;
}
ju fastshe(ju s,int k)
{//矩阵的k次方,快速幂
ju ans;
ans.init();
for(;k>0;k>>=1)
{
if(k&1)
ans=jumul(ans,s);
s=jumul(s,s) ;
}
return ans;
}
ju sss(ju s,int k)
{//(求A+A^2+A^3+....+A^k)
if (k==1)
return s;
ju tmp;
tmp.init();
tmp=juadd(tmp,fastshe(s,k>>1));
tmp=jumul(tmp,sss(s,k>>1));
if (k&1)
tmp=juadd(tmp,fastshe(s,k));
return tmp;
}
int main()
{
int t;
t=read();
while(t--)
{
n=read();m=read();
ju out;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
out.a[i][j]=0;
for(int i=0;i<n;i++)
{
int k;
k=read();
for(int j=0;j<k;j++)
{
int x;x=read();
out.a[i][x-1]=1;
}
}
int ans=n+1;
if(m==1)
{
write(ans);
puts("");
continue;
}
out=sss(out,m-1);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
ans+=out.a[i][j];
write(ans%mod);
puts("");
}
}