[hdu5411 CRB and Puzzle]DP,矩阵快速幂
题意:给一个有向图,从任意点开始,最多走m步,求形成的图案总数。
思路:令dp[i][j]表示走j步最后到达i的方法数,则dp[i][j]=∑dp[k][j-1],其中k表示可以直接到达i的点,答案=∑dp[i][j]。关键在于如何减少状态转移的时间,考虑用矩阵加速。
构造矩阵:D =
,其中a[i][j]表示有向图,用于状态转移,右边的一列1用于累加答案
则答案=[1,1,...1n+1]*DM-1=∑∑DM-1[i][j],1≤i≤n+1,1≤j≤n+1
PS:封装的ModInt放矩阵的最里面进行运算比直接取模慢了3倍多,因此在性能瓶颈地方尽量用最快的写法
#pragma comment(linker, "/STACK:10240000")
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; #define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a)) typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull; #ifndef ONLINE_JUDGE
void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
#endif
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);} const double PI = acos(-1.0);
const int INF = 1e9 + ;
const double EPS = 1e-12; /* -------------------------------------------------------------------------------- */ const int maxn = ; template<int mod>
struct ModInt {
const static int MD = mod;
int x;
ModInt(ll x = ): x(x % MD) {}
int get() { return x; } ModInt operator + (const ModInt &that) const { int x0 = x + that.x; return ModInt(x0 < MD? x0 : x0 - MD); }
ModInt operator - (const ModInt &that) const { int x0 = x - that.x; return ModInt(x0 < MD? x0 + MD : x0); }
ModInt operator * (const ModInt &that) const { return ModInt((long long)x * that.x % MD); }
ModInt operator / (const ModInt &that) const { return *this * that.inverse(); } ModInt operator += (const ModInt &that) { x += that.x; if (x >= MD) x -= MD; }
ModInt operator -= (const ModInt &that) { x -= that.x; if (x < ) x += MD; }
ModInt operator *= (const ModInt &that) { x = (long long)x * that.x % MD; }
ModInt operator /= (const ModInt &that) { *this = *this / that; } ModInt inverse() const {
int a = x, b = MD, u = , v = ;
while(b) {
int t = a / b;
a -= t * b; std::swap(a, b);
u -= t * v; std::swap(u, v);
}
if(u < ) u += MD;
return u;
} };
typedef ModInt<> mint; int N;
struct Matrix {
int a[maxn][maxn]; Matrix() {
for (int i = ; i < N; i ++) {
for (int j = ; j < N; j ++) {
a[i][j] = ;
}
}
} static Matrix unit() {
Matrix ans;
for (int i = ; i < N; i ++) ans.a[i][i] = ;
return ans;
} Matrix &operator * (const Matrix &that) const {
static Matrix ans;
for (int i = ; i < N; i ++) {
for (int j = ; j < N; j ++) {
ans.a[i][j] = ;
for (int k = ; k < N; k ++) {
ans.a[i][j] += a[i][k] * that.a[k][j];
ans.a[i][j] %= ;
}
}
}
return ans;
} static Matrix power(Matrix a, int n) {
Matrix ans = unit(), buf = a;
while (n) {
if (n & ) ans = ans * buf;
buf = buf * buf;
n >>= ;
}
return ans;
}
}; class Timer {
private:
clock_t _start;
clock_t _end; public:
void init() {
_start = clock();
}
void get() {
_end = clock();
cout << double(_end - _start) / CLK_TCK << endl;
}
};
Timer clk; int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int T, n, m, k, x;
cin >> T;
while (T --) {
cin >> n >> m;
Matrix a;
N = n + ;
for (int i = ; i < n; i ++) {
scanf("%d", &k);
for (int j = ; j < k; j ++) {
scanf("%d", &x);
a.a[i][-- x] = ;
}
}
for (int i = ; i < N; i ++) a.a[i][N - ] = ;
Matrix A = Matrix::power(a, m - );
mint ans = ;
for (int i = ; i < N; i ++) {
for (int j = ; j < N; j ++) {
ans += A.a[i][j];
}
}
cout << ans.get() << endl;
}
return ;
}
[hdu5411 CRB and Puzzle]DP,矩阵快速幂的更多相关文章
- HDU5411——CRB and Puzzle——————【矩阵快速幂优化dp】
CRB and Puzzle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- HDU 5411 CRB and puzzle (Dp + 矩阵高速幂)
CRB and Puzzle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) T ...
- bnuoj 34985 Elegant String DP+矩阵快速幂
题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 We define a kind of strings as elegant s ...
- HDU 5434 Peace small elephant 状压dp+矩阵快速幂
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant Accepts: 38 Submissions: ...
- 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂
[题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...
- 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂
[题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...
- BZOJ5298 CQOI2018 交错序列 【DP+矩阵快速幂优化】*
BZOJ5298 CQOI2018 交错序列 [DP+矩阵快速幂优化] Description 我们称一个仅由0.1构成的序列为"交错序列",当且仅当序列中没有相邻的1(可以有相邻 ...
- Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】
题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分 ...
- codeforces E. Okabe and El Psy Kongroo(dp+矩阵快速幂)
题目链接:http://codeforces.com/contest/821/problem/E 题意:我们现在位于(0,0)处,目标是走到(K,0)处.每一次我们都可以从(x,y)走到(x+1,y- ...
- [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)
[BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...
随机推荐
- 配置CORS代理请求
参考资料: Vue-CLI 3.x 跨域问题处理 使用代理设置:见官方文档 配置代理 新建配置文件 在 package.json 文件的同级目录下创建 vue.config.js 文件,文件的格式应该 ...
- Spring Data REST不完全指南(三)
上一篇我们介绍了使用Spring Data REST时的一些高级特性,以及使用代码演示了如何使用这些高级的特性.本文将继续讲解前面我们列出来的七个高级特性中的后四个.至此,这些特性能满足我们大部分的接 ...
- df卡住的解决办法
在使用网络存储时,如果网络存储出问题.比如使用NFS,网络中断,df -h会卡住 情形一 ctrl+c是能取消中断的,这种情况算是比较幸运.使用mount查看有哪些挂载点,将其卸载即可. 情形二 ct ...
- 使用 PyHamcrest 执行健壮的单元测试
在 测试金字塔 的底部是单元测试.单元测试每次只测试一个代码单元,通常是一个函数或方法. 通常,设计单个单元测试是为了测试通过一个函数或特定分支的特定执行流程,这使得将失败的单元测试和导致失败的 bu ...
- bm25算法和tfidf
- Java 自动拆箱 装箱 包装类的缓存问题--结合源码分析
都0202 了 java 1.8 已经是主流 自动装箱 .拆箱已经很普遍使用了,那么有时候是不是会遇到坑呢? 我们先来看一段代码: public class TestWraperClass { pub ...
- 如何保证kafka消息不丢失
背景 这里的kafka值得是broker,broker消息丢失的边界需要对齐一下: 1 已经提交的消息 2 有限度的持久化 如果消息没提交成功,并不是broke丢失了消息: 有限度的持久化(broke ...
- 使用 Python 控制自己的电脑和键盘是一种什么样的体验?python学习的正确姿势
可能有时候你需要在电脑做一些重复的点击或者提交表单等操作,如果能通过 Python 预先写好相关的操作指令,让它帮你操作,然后你自己爱干嘛干嘛去,有点 “按键精灵” 的意思,是不是感觉有点爽呢? 那么 ...
- thinkphp5.1+layui2.x 时间戳转换为日期格式
layui.use(['table','util'],function(){ var table = layui.table,form = layui.form; table.render({ ele ...
- 2019-2020-1 20199326《Linux内核原理与分析》第五周作业
第五周学习内容 庖丁解牛Linux内核分析第四章:系统调用的三层机制(上) Linux内核分析实验四 学到的一些知识 4.1用户态.内核态.中断 宏观上Linux操作系统的体系架构分为用户态和内核态 ...