• P5789 [TJOI2017]可乐 矩阵乘法


    P5789 [TJOI2017]可乐 矩阵乘法

    题目链接

    ​ 说实话这个自爆的问题难住我了, 其他的都还挺好想的.

    ​ 操作一 : 走到相邻的点, 如果(x)可以走到(y), 那么我们另(g[x][y] = g[y][x] = 1), 表示这两个点之间可以相互走.

    ​ 操作二 : 停在原地 , 相当于自己有一条到自己的边.

    ​ 操作三 : 自爆 , 我们可以假设有一个0点, 然后所有点都可以向0点连边, 而0点不能向外连边. 这个和自爆的性质是一样的.

    其实也蛮水的, TESknight零秒就切出来了%%%

    #include <bits/stdc++.h>
    
    using namespace std;
    
    inline long long read() {
    	long long s = 0, f = 1; char ch;
    	while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
    	for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
    	return s * f;
    }
    
    const int N = 105, mod = 2017;
    int n, m, k, ans_;
    struct mat {
    	int v[N][N];
    	void init() { for(int i = 0;i <= n; i++) for(int j = 0;j <= n; j++) v[i][j] = 0; }
    	friend mat operator * (const mat &a, const mat &b) {
    		mat c; c.init();
    		for(int k = 0;k <= n; k++)
    			for(int i = 0;i <= n; i++)
    				if(a.v[i][k])
    				for(int j = 0;j <= n; j++)
    					if(b.v[k][j]) c.v[i][j] = (c.v[i][j] + 1ll * a.v[i][k] * b.v[k][j] % mod) % mod; 
    		return c;
    	}
    } ans, turn;
    
    mat ksm(mat x, int y) {
    	mat res; res.init(); for(int i = 0;i <= n; i++) res.v[i][i] = 1;
    	while(y) { if(y & 1) res = res * x; x = x * x; y >>= 1; }
    	return res;
    }
    
    int main() {
    	
    	n = read(); m = read();
    	for(int i = 1, x, y;i <= m; i++) x = read(), y = read(), turn.v[x][y] = turn.v[y][x] = 1;
    	for(int i = 0;i <= n; i++) turn.v[i][0] = turn.v[i][i] = 1;
    	k = read(); ans = ksm(turn, k); 
    	for(int i = 0;i <= n; i++) ans_ = (ans_ + ans.v[1][i]) % mod;
    	printf("%d", ans_);
    
    	return 0;
    }
    
  • 相关阅读:
    HTML+CSS简单实现导航栏二级下拉菜单
    原创 | 我的个人微信公众号
    原创 | 喂,在吗?
    NodeJs实现邮箱验证
    JS排序算法(二)冒泡排序
    JS排序算法(一) 快速排序
    前端常见的布局方式
    JS继承方式
    前端Node实现简易的文件上传下载
    原生js实现深度克隆
  • 原文地址:https://www.cnblogs.com/czhui666/p/14014614.html
Copyright © 2020-2023  润新知