描述:
小易拥有一个拥有魔力的手环上面有n个数字(构成一个环),当这个魔力手环每次使用魔力的时候就会发生一种奇特的变化:每个数字会变成自己跟后面一个数字的和(最后一个数字的后面一个数字是第一个),一旦某个位置的数字大于等于100就马上对100取模(比如某个位置变为103,就会自动变为3).现在给出这个魔力手环的构成,请你计算出使用k次魔力之后魔力手环的状态。
输入描述:
输入数据包括两行:
第一行为两个整数n(2 ≤ n ≤ 50)和k(1 ≤ k ≤ 2000000000),以空格分隔
第二行为魔力手环初始的n个数,以空格分隔。范围都在0至99.
输出描述:
输出魔力手环使用k次之后的状态,以空格分隔,行末无空格。
输入例子:
3 2
1 2 3
输出例子:
8 9 7
分析:
由于题目中的求值非常有规律,数字成环,且当前数字等于当前数字加上后面的一个数字,自然就可以联想到构造矩阵,而且看到操作次数那么大,肯定要么找规律,要么快速幂,然后我打表并没有发现什么规律,所以矩阵快速幂。
#include<bits/stdc++.h>
using namespace std;
vector<vector<int> > mul(vector<vector<int> >a,vector<vector<int> >b)
{
int m=a.size(),n=a[0].size(),k=b[0].size();
vector<vector<int> > res(m,vector<int>(k,0));
for(int i=0;i<m;i++)
for(int j=0;j<k;j++)
for(int f=0;f<n;f++)
res[i][j] = (res[i][j]+a[i][f]*b[f][j])%100;
return res;
}
vector<vector<int> > matrix_pow(vector<vector<int> > matrix,int k)
{
int n=matrix.size();
vector<vector<int> > mm(n,vector<int>(n,0));
for(int i=0;i<n;i++)
mm[i][i]=1;
while(k){
if(k&1)
mm = mul(matrix,mm);
matrix = mul(matrix,matrix);
k>>=1;
}
return mm;
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
vector<vector<int> > num;
vector<int> t;
int tmp;
for(int i=0;i<n;i++){
scanf("%d",&tmp);
t.push_back(tmp);
}
num.push_back(t);
vector<vector<int> > matrix(n,vector<int>(n,0));
for(int i=0;i<n;i++){
matrix[i][i]=1;
matrix[(i+1)%n][i]=1;
}
vector<vector<int> > mm = matrix_pow(matrix,k);
vector<vector<int> > ans = mul(num,mm);
printf("%d",ans[0][0]);
for(int i=1;i<ans[0].size();i++)
printf(" %d",ans[0][i]);
puts("");
return 0;
}