zoukankan      html  css  js  c++  java
  • BZOJ4162:shlw loves matrix II

    传送门
    利用Cayley-Hamilton定理,用插值法求出特征多项式 (P(x))
    然后 (M^nequiv M^n(mod~P(x))(mod~P(x)))
    然后就多项式快速幂+取模
    最后得到了一个关于 (M) 的多项式,代入 (M^i) 即可

    # include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int mod(1e9 + 7);
    
    inline int Pow(ll x, int y) {
    	register ll ret = 1;
    	for (; y; y >>= 1, x = x * x % mod)
    		if (y & 1) ret = ret * x % mod;
    	return ret;
    }
    
    inline void Inc(int &x, int y) {
    	x = x + y >= mod ? x + y - mod : x + y;
    }
    
    inline int Dec(int x, int y) {
    	return x - y < 0 ? x - y + mod : x - y;
    }
    
    int n, m, a[55][55], b[55][55], mt[55][55], tmt[55][55], len, c[55], d[55], p[55], tmp[105], yi[55];
    char str[10005];
    
    inline int Gauss() {
    	register int i, j, k, inv, ans = 1;
    	for (i = 1; i <= n; ++i) {
    		for (j = i; j <= n; ++j)
    			if (b[j][i]) {
    				if (i != j) swap(b[i], b[j]), ans = mod - ans;
    				break;
    			}
    		for (j = i + 1; j <= n; ++j)
    			if (b[j][i]) {
    				inv = (ll)b[j][i] * Pow(b[i][i], mod - 2) % mod;
    				for (k = i; k <= n; ++k) Inc(b[j][k], mod - (ll)b[i][k] * inv % mod);
    			}
    		ans = (ll)ans * b[i][i] % mod;
    	}
    	return ans;
    }
    
    inline void Mul(int *x, int *y, int *z) {
    	register int i, j, inv;
    	memset(tmp, 0, sizeof(tmp));
    	for (i = 0; i <= n; ++i)
    		for (j = 0; j <= n; ++j) Inc(tmp[i + j], (ll)x[i] * y[j] % mod);
    	for (i = m; i >= n; --i) {
    		inv = (ll)tmp[i] * Pow(p[n], mod - 2);
    		for (j = 0; j <= n; ++j) Inc(tmp[i - j], mod - (ll)p[n - j] * inv % mod);
    	}
    	for (i = 0; i <= n; ++i) z[i] = tmp[i];
    }
    
    int main() {
    	register int i, j, k, l, inv;
    	scanf(" %s%d", str + 1, &n), len = strlen(str + 1), m = n << 1;
    	for (i = 1; i <= n; ++i)
    		for (j = 1; j <= n; ++j) scanf("%d", &a[i][j]);
    	for (i = 0; i <= n; ++i) {
    		memset(b, 0, sizeof(b));
    		for (j = 1; j <= n; ++j)
    			for (k = 1; k <= n; ++k)
    				b[j][k] = (j ^ k) ? mod - a[j][k] : Dec(i, a[j][k]);
    		yi[i] = Gauss();
    	}
    	for (i = 0; i <= n; ++i) {
    		memset(tmp, 0, sizeof(tmp)), tmp[0] = yi[i];
    		for (j = 0; j <= n; ++j)
    			if (j ^ i) {
    				for (k = n; k; --k) tmp[k] = Dec(tmp[k - 1], (ll)tmp[k] * j % mod);
    				tmp[0] = mod - (ll)tmp[0] * j % mod, inv = Pow(Dec(i, j), mod - 2);
    				for (k = 0; k <= n; ++k) tmp[k] = (ll)tmp[k] * inv % mod;
    			}
    		for (j = 0; j <= n; ++j) Inc(p[j], tmp[j]);
    	}
    	c[0] = d[1] = 1;
    	for (i = len; i; --i) {
    		if (str[i] == '1') Mul(c, d, c);
    		Mul(d, d, d);
    	}
    	memset(b, 0, sizeof(b));
    	for (i = 1; i <= n; ++i) mt[i][i] = 1;
    	for (l = 0; l <= n; ++l) {
    		for (i = 1; i <= n; ++i)
    			for (j = 1; j <= n; ++j)
    				Inc(b[i][j], (ll)c[l] * mt[i][j] % mod);
    		memset(tmt, 0, sizeof(tmt));
    		for (i = 1; i <= n; ++i)
    			for (j = 1; j <= n; ++j)
    				for (k = 1; k <= n; ++k)
    					Inc(tmt[i][k], (ll)mt[i][j] * a[j][k] % mod);
    		memcpy(mt, tmt, sizeof(mt));
    	}
    	for (i = 1; i <= n; ++i, putchar('
    '))
    		for (j = 1; j <= n; ++j) printf("%d ", b[i][j]);
    	return 0;
    }
    
  • 相关阅读:
    Cryptography中的对称密钥加解密:fernet算法探究
    HTTPS的工作原理
    最近要写的博客
    浅谈路由器软硬件架构
    组管理、权限管理、定时任务调度、磁盘分区
    matplotlib数据可视化
    tensorflow实现简单的卷积神经网络
    tensorflow实现简单的感知机
    tensorflow实现简单的自编码器
    区域生长算法(手动选取种子点)MATLAB
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/10198777.html
Copyright © 2011-2022 走看看