链接

题解链接:http://www.cygmasot.com/index.php/2015/08/20/hdu_5411/

给定n个点 常数m

以下n行第i行第一个数字表示i点的出边数。后面给出这些出边。

问:图里存在多少条路径使得路径长度<=m。路径上的点能够反复。

思路:

首先能得到一个m*n*n的dp。dp[i][j]表示路径长度为i 路径的结尾为j的路径个数 。

答案就是sigma(dp[i][j]) for every i from 1 to m, j from 1 to n;

我们先计算 路径长度恰好为 i 的方法数。

用矩阵高速幂,会发现是

当中B矩阵是一个n*n的矩阵。也就是输入的邻接矩阵。

A是一个n行1列的矩阵 A[i][1]表示长度为1且以i结尾的路径个数,所以A矩阵是全1矩阵。

相乘得到的n*1 的矩阵求和就是路径长度恰好为i的条数。

那么<=m的路径就是:

把A提出来,里面就是一个关于B的矩阵等比数列。

B的求发主要是二分。详见POJ3233

模板不大好,交G++能过

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<ctime> using namespace std;
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if (x>9) pt(x / 10);
putchar(x % 10 + '0');
}
const int mod = 2015;
const int N = 51; struct Matrix
{
int m[N][N];
}G[2000];
int top;
Matrix I;
int n, k;
const int M = 2015;
Matrix add(Matrix a, Matrix b)
{
Matrix &c = G[top++];
for (int i = 0; i<n; i++)
{
for (int j = 0; j<n; j++)
{
c.m[i][j] = a.m[i][j] + b.m[i][j];
c.m[i][j] %= M;
}
}
top--;
return c;
} Matrix multi(Matrix a, Matrix b)
{
Matrix &c = G[top++];
for (int i = 0; i<n; i++)
{
for (int j = 0; j<n; j++)
{
c.m[i][j] = 0;
for (int k = 0; k<n; k++)
c.m[i][j] += a.m[i][k] * b.m[k][j];
c.m[i][j] %= M;
}
}
top--;
return c;
} Matrix power(Matrix A, int n)
{
Matrix &ans = G[top++], &p = G[top++];
ans = I; p = A;
while (n)
{
if (n & 1)
{
ans = multi(ans, p);
n--;
}
n >>= 1;
p = multi(p, p);
}
top -= 2;
return ans;
} Matrix sum(Matrix A, int k)
{
if (k == 1) return A;
Matrix &t = G[top++];
t = sum(A, k / 2);
if (k & 1)
{
Matrix &cur = G[top++];
cur = power(A, k / 2 + 1);
t = add(t, multi(t, cur));
t = add(t, cur);
top--;
}
else
{
Matrix &cur = G[top++];
cur = power(A, k / 2);
t = add(t, multi(t, cur));
top--;
}
top--;
return t;
} int m;
void add(int &x, int y){
x += y;
if (x >= mod)x -= mod;
}
int B[N][N];
int main(){
memset(I.m, 0, sizeof I.m);
for (int i = 0; i < N; i++)I.m[i][i] = 1;
int T; rd(T);
while (T--){
rd(n); rd(m);
Matrix A;
top = 0;
memset(A.m, 0, sizeof A.m);
for (int i = 1; i <= n; i++) {
int tmp; rd(tmp); while (tmp--) { int u; rd(u); A.m[i-1][u-1] = 1; }
}
if (m == 0) { puts("1"); continue; }
if (m == 1){ pt(n + 1); puts(""); continue; }
Matrix ans = sum(A, m-1);
for (int i = 0; i<n; i++)
for (int j = 0; j<n; j++)
B[i][j] = ans.m[i][j]; for (int i = 0; i < n; i++)B[i][i] ++;
int hehe = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
add(hehe, B[i][j]);
}
pt(1 + hehe); puts("");
}
return 0;
}
/*
99
1 10
1 1 3 100000
3 1 2 3
3 1 2 3
3 1 2 3 5 3
5 1 2 3 4 5
4 2 3 4 5
3 1 3 5
5 1 2 3 4 5
3 1 2 3 */

hdu 5411 CRB and Puzzle 矩阵高速幂的更多相关文章

  1. hdu 5411 CRB and Puzzle (矩阵高速幂优化dp)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5411 题意:按题目转化的意思是,给定N和M,再给出一些边(u,v)表示u和v是连通的,问走0,1,2... ...

  2. HDOJ 5411 CRB and Puzzle 矩阵高速幂

    直接构造矩阵,最上面一行加一排1.高速幂计算矩阵的m次方,统计第一行的和 CRB and Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  3. HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和)

    HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和) ACM 题目地址:HDU 1588 Gauss Fibonacci 题意:  g(i)=k*i+b;i为变量.  给出 ...

  4. HDU 5411 CRB and puzzle (Dp + 矩阵高速幂)

    CRB and Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) T ...

  5. HDU 5411 CRB and Puzzle (2015年多校比赛第10场)

    1.题目描写叙述:pid=5411">点击打开链接 2.解题思路:本题实际是是已知一张无向图.问长度小于等于m的路径一共同拥有多少条. 能够通过建立转移矩阵利用矩阵高速幂解决.当中,转 ...

  6. HDU 2256 Problem of Precision(矩阵高速幂)

    题目地址:HDU 2256 思路: (sqrt(2)+sqrt(3))^2*n=(5+2*sqrt(6))^n; 这时要注意到(5+2*sqrt(6))^n总能够表示成an+bn*sqrt(6); a ...

  7. hdu 4965 Fast Matrix Calculation(矩阵高速幂)

    题目链接.hdu 4965 Fast Matrix Calculation 题目大意:给定两个矩阵A,B,分别为N*K和K*N. 矩阵C = A*B 矩阵M=CN∗N 将矩阵M中的全部元素取模6,得到 ...

  8. 2015 Multi-University Training Contest 10 hdu 5411 CRB and Puzzle

    CRB and Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  9. HDU - 1588 Gauss Fibonacci (矩阵高速幂+二分求等比数列和)

    Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r a very cle ...

随机推荐

  1. EasyUI DataGrid组织事件冒泡

    在事件内部需要阻止的地方添加如下代码 ]; 解释: arguments.callee是获得我自定义的事件处理方法OnSelected的方法体. .caller是获得调用OnSelected的上层方法( ...

  2. 第一课trie 树 POJ 2001

    最短前缀(Openjudge上抄的) 总时间限制: 1000ms 内存限制: 65536kB 描述 一个字符串的前缀是从该字符串的第一个字符起始的一个子串.例如 "carbon"的 ...

  3. ACM_Exponentiation

    Exponentiation Time Limit: 2000/1000ms (Java/Others) Problem Description: Problems involving the com ...

  4. R - Games

    Problem description Manao works on a sports TV. He's spent much time watching the football games of ...

  5. [跨域]js设置document.domain实现跨域

    document.domain用来得到当前网页的域名.比如在地址栏里输入: 代码如下: javascript:alert(document.domain); //www.jb51.net 我们也可以给 ...

  6. 如何使用Visual Studio调试C#程序

    当代码不能正常运行时,可以通过调试定位错误.常用的程序调试操作包括设置断点.开始.中断和停止程序的执行.单步执行程序以及使程序运行到指定的位置.下面将对这几种常用的程序调试操作进行详细地介绍. 1.断 ...

  7. OpenCV:OpenCV图像旋转的代码

    OpenCV图像旋转的代码 cv::transpose( bfM, bfM ) 前提:使用两个矩阵Mat型进行下标操作是不行的,耗费的时间太长了.直接使用两个指针对拷贝才是王道.不知道和OpenCV比 ...

  8. 【sicily】 1934. 移动小球

    Description 你有一些小球,从左到右依次编号为1,2,3,...,n. 你可以执行两种指令(1或者2).其中, 1 X Y表示把小球X移动到小球Y的左边, 2 X Y表示把小球X移动到小球Y ...

  9. linux环境jdk安装及配置

    linux环境jdk安装及配置 linux环境jdk安装及配置 1.下载jkd( http://www.oracle.com/technetwork/java/javase/downloads/ind ...

  10. 【sqli-labs】 less6 GET - Double Injection - Double Quotes - String (双注入GET双引号字符型注入)

    同less5 单引号改成双引号就行 http://localhost/sqli/Less-6/?id=a" union select 1,count(*),concat((select ta ...