六芒星 | ||||||
| ||||||
Description | ||||||
石堆消失之后,wd和Cc进入到了洞中。Wd惊奇的发现洞中是一个空旷的大厅,在大厅的中央有一个巨大的六芒星,在这颗六芒星的六个角上分别对应着六个数字x1,x2,x3,x4,x5,x6,这时走过来一个神秘的使者,使者告诉他们要想见到神龙必须回答他的问题,否则他将誓死捍卫神龙,wd看到了使者手中闪闪发光的武器—蒜伐导轮,知道回答问题是避免不了的了,于是wd再次拿出了他的神器。 使者说:中央这颗六芒星上的数据会同时进行变换,变换的规则是每个数字加上除了位于它正对面的其余数字,得到的和再对 m 取模,当 k 次变换之后这六个位置的数字依次是什么?(例如:x1位置的数在一次变换之后带到的数字为(x1+x2+x3+x5+x6)%m) | ||||||
Input | ||||||
多组测试数据:每组测试数据占两行 第一行两个整数m,k ,意义如题面描述。(1<=m<=1000000000,1<=k<=1000000000) 第二行六个整数x1,x2,x3,x4,x5,x6表示六芒星六个角上的初始数字。(0<=xi<=100) | ||||||
Output | ||||||
对于每组数据,输出六个整数占一行,分别表示x1..x6在k次变换之后得到的数字。 | ||||||
Sample Input | ||||||
100000 1 1 2 3 4 5 6 | ||||||
Sample Output | ||||||
17 16 15 20 19 18 |
思路:
一看到K的范围,不用多想,矩阵快速幂优化递推式没得跑。
对于递推式题目已经明确给出,这个题没有什么技术含量,会敲矩阵快速幂和构造矩阵即可,这里我们还是贴出如何构造矩阵:
剩下的就是完成代码实现部分,AC代码:
#include<stdio.h>
#include<string.h>
using namespace std;
#define ll long long int
ll mod,n;
typedef struct Matrix
{
ll mat[6][6];
}matrix;
matrix A,B,tmp;
Matrix matrix_mul(matrix a,matrix b)
{
matrix c;
memset(c.mat,0,sizeof(c.mat));
int i,j,k;
for(int i=0;i<6;i++)
{
for(int j=0;j<6;j++)
{
for(int k=0;k<6;k++)
{
c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
c.mat[i][j]%=mod;
}
}
}
return c;
}
Matrix matrix_quick_power(matrix a,ll k)//矩阵快速幂0.0
{
matrix b;
memset(b.mat,0,sizeof(b.mat));
for(int i=0;i<6;i++)
b.mat[i][i]=1;//单位矩阵b
while(k)
{
if(k%2==1)
{
b=matrix_mul(a,b);
k-=1;
}
else
{
a=matrix_mul(a,a);
k/=2;
}
}
return b;
}
int main()
{
while(~scanf("%lld%lld",&mod,&n))
{
memset(tmp.mat,0,sizeof(tmp.mat));
for(int i=0;i<6;i++)
{
scanf("%lld",&tmp.mat[i][0]);
}
for(int i=0;i<6;i++)
{
for(int j=0;j<6;j++)
{
A.mat[i][j]=1;
}
}
A.mat[0][3]=0;A.mat[1][4]=0;A.mat[2][5]=0;A.mat[3][0]=0;A.mat[4][1]=0;A.mat[5][2]=0;
B=matrix_quick_power(A,n);
B=matrix_mul(B,tmp);
for(int i=0;i<6;i++)
{
if(i==5)
{
printf("%lld\n",B.mat[i][0]);
}
else
printf("%lld ",B.mat[i][0]);
}
}
}