zoukankan      html  css  js  c++  java
  • 题解 P3758 【[TJOI2017]可乐】

    题目链接

    树形(dp)多半是跑不过去的,可用矩阵快速幂解决

    [TJOI2017]可乐

    题目大意:给定一个无向图,(0)秒时机器人在(1)号点,每秒可以走到另一个相邻的点或者不动或者自爆,求(t)秒内行动方案数

    矩阵快速幂


    分析:首先把问题统一,不动我们连自环即可,自爆可以连单向边到虚拟点,虚拟点连自环,然后问题就变成了(t)秒后走到每个点的方案数之和

    假设用(f[t][u])表示在(t)秒时走到(u)点的方案数,显然(f[t][u] = sum f[t-1][v]),有边((u,v)),然后假设我们知道当前的(f),把它构成一个矩阵

    (egin{pmatrix}f(1),f(2)dots f(n)end{pmatrix})

    然后我们发现将其乘上邻接矩阵(G)就可以得到下一秒的(f)值,然后就可以矩阵快速幂解决

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <vector>
    using namespace std;
    const int maxn = 32,mod = 2017;
    inline int read(){
    	int x = 0;char c = getchar();
    	while(!isdigit(c))c = getchar();
    	while(isdigit(c))x = x * 10 + c - '0',c = getchar();
    	return x;
    }
    struct matrix{
    	int val[maxn][maxn],x,y;
    	matrix operator * (const matrix &rhs)const{
    		matrix res;
    		res.x = x;
    		res.y = rhs.y;
    		for(int i = 1;i <= res.x;i++)
    			for(int j = 1;j <= res.y;j++)res.val[i][j] = 0;
    		for(int i = 1;i <= res.x;i++)
    			for(int j = 1;j <= res.y;j++)
    				for(int k = 1;k <= y;k++)
    					res.val[i][j] = (res.val[i][j] + val[i][k] * rhs.val[k][j]) % mod;
    		return res;
    	}
    }G,ans;
    int n,m,t,out;
    inline matrix qpow(const matrix &a,int b){
    	matrix res,base = a;
    	res.x = res.y = a.x;
    	for(int i = 1;i <= res.x;i++)
    		for(int j = 1;j <= res.y;j++)
    			res.val[i][j] = 0;
    	for(int i = 1;i <= res.x;i++)
    		res.val[i][i] = 1;
    	while(b){
    		if(b & 1)res = res * base;
    		base = base * base;
    		b >>= 1;
    	}
    	return res;
    }
    int main(){
    	n = read() + 1,m = read();
    	G.x = G.y = n;
    	for(int u,v,i = 1;i <= m;i++)
    		u = read(),v = read(),G.val[u][v] = G.val[v][u] = 1;
    	t = read();
    	for(int i = 1;i <= n;i++)G.val[i][i] = 1;
    	for(int i = 1;i <= n - 1;i++)G.val[i][n] = 1;
    	ans.x = 1,ans.y = n;
    	ans.val[1][1] = 1;
    	ans = ans * qpow(G,t);
    	for(int i = 1;i <= n;i++)
    		out = (out + ans.val[1][i]) % mod;
    	printf("%d
    ",out);
    	return 0;
    }
    
  • 相关阅读:
    2019-7-3-WPF-使用-Composition-API-做高性能渲染
    2019-7-3-WPF-使用-Composition-API-做高性能渲染
    2018-8-10-win10-uwp-禁止编译器优化代码
    2018-8-10-win10-uwp-禁止编译器优化代码
    2018-2-13-wpf-如何使用-Magick.NET-播放-gif-图片
    2018-2-13-wpf-如何使用-Magick.NET-播放-gif-图片
    2019-8-31-Developing-Universal-Windows-Apps-开发UWA应用-问答
    2019-8-31-Developing-Universal-Windows-Apps-开发UWA应用-问答
    2019-3-1-WPF-从零开始开发-dotnet-Remoting-程序
    busybox
  • 原文地址:https://www.cnblogs.com/colazcy/p/11736990.html
Copyright © 2011-2022 走看看