hihoCoder 编程练习赛70 - D 神奇的序列 (构造矩阵)

版权声明:是自己手打的没错 https://blog.csdn.net/Mr_Treeeee/article/details/81273507

https://hihocoder.com/contest/offers70/problem/4

POINT:

就是一道比较简单的构造矩阵的问题。

然后用矩阵快速幂来算答案。

思路是把一个1*n的矩阵{a1,a2,a3,a4,an} 右乘一个n*n的矩阵 变为{a2,a3,a4,,a5,an+1}。

构造这个矩阵就很简单了。

这题在赛中数据有错,睡了一觉上去看AC了。应该重判了。也只能在那么水的比赛上拿个第一名了。

 

 

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <string>
using namespace std;
#define  LL long long
const LL maxn  = 22;
const LL mod = 1e9+9;
LL a[22];
LL n;
struct node
{
	LL a[maxn][maxn];
	void init(){
		memset(a,0,sizeof a);
	}
	node friend operator * (node a,node b)
	{
		node c;
		c.init();
		for(LL i=1;i<=n;i++){
			for(LL j=1;j<=n;j++){
				for(LL k=1;k<=n;k++){
					c.a[i][j]+=a.a[i][k]*b.a[k][j];
					c.a[i][j]%=mod;
				}
			}
		}
		return c;
	}
};

int main()
{
	LL m,c;
	scanf("%lld%lld%lld",&n,&m,&c);
	for(LL i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	node b;
	b.init();
	for(LL i=1;i<n;i++){
		b.a[i+1][i]=1;
	}
	for(LL i=1;i<=c;i++){
		LL x;scanf("%lld",&x);
		b.a[n+1-x][n]++;
	}
	if(m<=n){
		printf("%lld\n",a[m]);
	}else{
		node ans;
		ans.init();
		for(LL i=1;i<=n;i++) ans.a[i][i]=1;
		m-=n;
		while(m){
			if(m&1) ans=ans*b;
			b=b*b;
			m>>=1;
		}
		LL z=0;
		for(LL i=1;i<=n;i++){
			z+=a[i]*ans.a[i][n];
			z%=mod;
		}
		printf("%lld\n",z);
	}





}

 

阅读更多
换一批

没有更多推荐了,返回首页