碧云天,黄叶地,秋色连波,波上寒烟翠。
山映斜阳天接水,芳草无情,更在斜阳外。
黯乡魂,追旅思,夜夜除非,好梦留人睡。
明月楼高休独倚,酒入愁肠,化作相思泪。
-----范仲淹《苏幕遮·碧云天》
矩阵幂求和可以将原矩阵最右边加上一列全1
例如原矩阵为A
1 1
0 1
要求A^0 + A^1+...+ A^(m-1)+ A^m
改为矩阵B
1 1 1
0 1 1
0 0 1
求B^m
最后最右列求和即为答案,具体根据题目要求对个别赋值进行修改
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <set>
#include <cmath>
#include <queue>
#define INF 0x3f3f3f3f
#define lowbit(x) (x&-x)
#define dbg(x) (cout<<"===="<<x<<endl)
#define dbg1(x) (cout<<"==="<<x)
using namespace std;
const double eps=1e-9;
#define mod 2015
typedef long long ll;
#define maxn 55
int siz;
struct mat
{
int d[maxn][maxn];
void print()
{
for (int i=0; i<siz; i++)
{
for (int j=0; j<siz; j++)
printf("%d ", d[i][j]);
printf("\n");
}
}
void init()
{
for (int i=0; i<siz; i++)
for (int j=0; j<siz; j++)
d[i][j] = 0;
}
mat()
{
init();
}
mat operator *(const mat&b)
{
mat c; //c.init();
for (int i=0; i<siz; i++)
for (int k=0; k<siz; k++)
for (int j=0; j<siz; j++)
c.d[i][j] = (c.d[i][j]+d[i][k]*b.d[k][j])%mod;
return c;
}
mat pow(int x)
{
mat a, b = *this;
for (int f = 0; x; x >>= 1)
{
if (x & 1)
if (f) a = a * b; else a = b, f = 1;
b = b * b;
}
return a;
}
};
mat aa;
int main()
{
// freopen("in.txt", "r", stdin);
int t;
cin >> t;
while (t--)
{
int n, m;
scanf("%d %d", &n, &m);
siz = n+1;
aa.init();
for (int i=1; i<=n; i++)
{
int k, p;
scanf("%d", &k);
for (int j=0; j<k; j++)
{
scanf("%d", &p);
aa.d[i-1][p-1] = 1;
}
}
for (int i=0; i<=n; i++)
aa.d[i][n] = 1;
aa = aa.pow(m);
int ans = 0;
//aa.print();
for (int i=0; i<=n; i++)
ans = (ans+aa.d[i][n])%mod;
printf("%d\n", ans);
}
return 0;
}