ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Different Pass a Ports(矩阵快速幂板子)

2022-08-29 03:00:08  阅读:221  来源: 互联网

标签:Different const matrix int res void Pass include Ports


Different Pass a Ports(矩阵快速幂)

题目大意:小明(化名)喜欢旅游,没到一个地方都会搜集该地的邮票并且按照旅游的顺序收藏,他可以进行K时间的旅行,每去一个地方就要花1时间。问k时间后,小明有多少种邮票的排序方式。小明从1这个点位出发。

经典的固定时间,经典的问固定时间后有多少种走法,直接矩阵快速幂(可以求出长度为固定值的路径有多少条)

AC代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define ll long long
using namespace std;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
struct matrix
{
	static const int n=110;
	int M[n][n];
	int N;
	matrix(int num)
	{
		N=num;
		memset(M,0,sizeof(M));
	}
	void build(){//把一个新的矩阵构造成单位阵
		for(int i=1;i<=N;i++)M[i][i]=1;
	}
	int *operator[](int i){//直接取出该位置的值,就不用每次都要调用M
		return M[i];
	}
	matrix operator*(matrix&a)
	{
		matrix temp(N);
		for(int i=1;i<=N;i++)
			for(int j=1;j<=N;j++)
				for(int k=1;k<=N;k++)
					temp[i][j]=(temp[i][j]+(1LL*M[i][k]*a[k][j])%mod)%mod;
		return temp;
	}
	matrix operator^(long long P)//矩阵快速幂
	{
		matrix res(N);res.build();
		matrix A=*this;
		while(P>0){
			if(P&1)
				res=res*A;
			A=A*A;
			P>>=1;
		}
		return res;
	}
};
int main(void)
{
	int N,M,K;scanf("%d %d %d",&N,&M,&K);
	matrix res(N);
	for(int i=0;i<M;i++)
	{
		int x,y;scanf("%d %d",&x,&y);
		res[x][y]++;
		res[y][x]++;
	}
	ll ans=0;
	res=res^K;
		for(int j=1;j<=N;j++)
			ans=(ans+res[1][j])%mod;
	cout<<ans<<endl;
	return 0;
}

与这道题类似的还有这道:

可乐

这道题多了一个爆炸的选择,就相当于每个点都有向着一个爆炸这个位置移动的边,且该位置的出度为0,不能出去。只需要每个点多连一条边到爆炸这个点就行了,然后矩阵快速幂跑一遍

AC代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
const int maxn=110;
const int INF=0x3f3f3f3f;
const int mod=2017;
struct matrix
{
    static const int n=maxn;
    ll M[n][n];
    int N;
    matrix(int num)
    {
    	N=num;
    	memset(M,0,sizeof(M));
    }
    void build(){
    	for(int i=1;i<=N;i++)M[i][i]=1;
    }
    ll* operator[](int i){
    	return M[i];
    }
    matrix operator*(matrix &a)
    {
    	matrix temp(N);
    	for(int i=1;i<=N;i++)
    		for(int j=1;j<=N;j++)
    			for(int k=1;k<=N;k++)
    				temp[i][j]=(temp[i][j]+(1LL*M[i][k]*a[k][j])%mod)%mod;
    	return temp;
    }
    matrix operator^(ll P)
    {
    	matrix res(N);res.build();
    	matrix A=*this;
    	while(P>0){
    		if(P&1)
    			res=res*A;
    		A=A*A;
    		P>>=1;
    	}
    	return res;
    }
};
int main(void)
{
	int N,M,K;
	scanf("%d %d",&N,&M);
	matrix res(N+1);res.build();//题目中有呆着原地这个选项,如果没有的话就不用
	for(int i=0;i<M;i++)
	{
		int x,y;
		scanf("%d %d",&x,&y);
		res[x][y]++;//可能存在多条相同的路
		res[y][x]++;
	}
	for(int i=1;i<=N;i++)res[i][N+1]++;//爆炸的情况,N+1为爆炸那个位置
	scanf("%d",&K);
	res=res^K;
	ll ans=0;
	for(int j=1;j<=N+1;j++)ans+=res[1][j];
	cout<<ans%mod<<endl;
	return 0;
}

背模板!!背模板!!

标签:Different,const,matrix,int,res,void,Pass,include,Ports
来源: https://www.cnblogs.com/WUTONGHUA02/p/16634641.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有