zoukankan      html  css  js  c++  java
  • bzoj1297 [SCOI2009]迷路 矩阵快速幂

    题目传送门

    https://lydsy.com/JudgeOnline/problem.php?id=1297

    题解

    如果每一条边没有边权,那么就是一般的矩阵快速幂。

    因为边权 (in [1, 9]),所以我们可以把每一个点拆成 (9) 个点,对于一条边权为 (w) 的边 (x o y),可以建立一条边 (x_{w-1} o y_0)

    然后 (x_i o x_{i+1}) 连边。

    然后矩阵快速幂就可以了。


    #include<bits/stdc++.h>
    
    #define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
    #define dbg(...) fprintf(stderr, __VA_ARGS__)
    #define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
    #define fi first
    #define se second
    #define pb push_back
    
    template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
    template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}
    
    typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
    
    template<typename I> inline void read(I &x) {
    	int f = 0, c;
    	while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    	x = c & 15;
    	while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    	f ? x = -x : 0;
    }
    
    const int N = 90 + 3;
    const int P = 2009;
    
    int n, m, T;
    char s[N];
    
    inline int smod(int x) { return x >= P ? x - P : x; }
    inline void sadd(int &x, const int &y) { x += y; x >= P ? x -= P : x; }
    inline int fpow(int x, int y) {
    	int ans = 1;
    	for (; y; y >>= 1, x = x * x % P) if (y & 1) ans = ans * x % P;
    	return ans;
    }
    
    struct Matrix {
    	int a[N][N];
    	
    	inline Matrix() { memset(a, 0, sizeof(a)); }
    	inline Matrix(const int &x) {
    		memset(a, 0, sizeof(a));
    		for (int i = 1; i <= m; ++i) a[i][i] = x;
    	}
    	
    	inline Matrix operator * (const Matrix &b) {
    		Matrix c;
    		for (int k = 1; k <= m; ++k)
    			for (int i = 1; i <= m; ++i)
    				for (int j = 1; j <= m; ++j)
    					sadd(c.a[i][j], a[i][k] * b.a[k][j] % P);
    		return c;
    	}
    } A;
    
    inline Matrix fpow(Matrix x, int y) {
    	Matrix ans(1);
    	for (; y; y >>= 1, x = x * x) if (y & 1) ans = ans * x;
    	return ans;
    }
    
    inline void work() {
    	m = 9 * n;
    	A = fpow(A, T);
    	printf("%d
    ", A.a[1][n]);
    }
    
    inline void init() {
    	read(n), read(T);
    	for (int i = 1; i <= n; ++i) {
    		scanf("%s", s + 1);
    		for (int j = 1; j <= n; ++j)
    			if (s[j] != '0') A.a[i + (s[j] - '1') * n][j] = 1;
    	}
    	for (int i = 1; i <= n; ++i)
    		for (int j = 0; j < 9 - 1; ++j)
    			A.a[i + j * n][i + (j + 1) * n] = 1;
    }
    
    int main() {
    #ifdef hzhkk
    	freopen("hkk.in", "r", stdin);
    #endif
    	init();
    	work();
    	fclose(stdin), fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    SharePoint 2013 图文开发系列之自定义字段
    SharePoint 2013 图文开发系列之Visual Studio 创建母版页
    SharePoint 2013 图文开发系列之代码定义列表
    SharePoint 2013 图文开发系列之计时器任务
    SharePoint 2013 图文开发系列之应用程序页
    SharePoint 2013 图文开发系列之事件接收器
    SharePoint 2013 图文开发系列之可视化WebPart
    SharePoint 2013 图文开发系列之WebPart
    SharePoint 2013 对二进制大型对象(BLOB)进行爬网
    SharePoint 2013 状态机工作流之日常报销示例
  • 原文地址:https://www.cnblogs.com/hankeke/p/bzoj1297.html
Copyright © 2011-2022 走看看