Problem 1692 Key problem
Accept: 208 Submit: 892
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
Input
Output
Each case separated by a space. See sample.
Sample Input
1 3 2 3 4 10000 1 2 3
Sample Output
120 133 131
Source
FOJ月赛-2009年3月--- Coral
题意:每次按a[i]=(a[i]+L*a[(i+1)%n]+R*a[(i-1+n)%n])%M(原题打错了),操作m次后n个数的结果
矩阵很好想,自己做的时候想对了,竟然T了,自己还是太水了
1 L 0 0 0 0 R a[0]
R 1 L 0 0 0 0 a[1]
0 R 1 L 0 0 0 a[2]
. . . . . . . a[n-1](依次类推)
写矩阵乘法的时候如果直接3重循环的话,假设数据范围是100X100的矩阵,就要花1e6的时间,肯定T了,通过观察可以发现,矩阵第一行和第二行变化规律一样,可以直接有第一个转换过来
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
#define pi acos(-1.0)
#define eps 1e-10
#define pf printf
#define sf scanf
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define e tree[rt]
#define _s second
#define _f first
#define all(x) (x).begin,(x).end
#define mem(i,a) memset(i,a,sizeof i)
#define for0(i,a) for(int (i)=0;(i)<(a);(i)++)
#define for1(i,a) for(int (i)=1;(i)<=(a);(i)++)
#define mi ((l+r)>>1)
#define sqr(x) ((x)*(x))
const int inf=0x3f3f3f3f;
int t,M,n,m,L,R;
ll ans[110][110],a[110],p[110][110];
void multi(ll a[][110],ll b[][110])//矩阵乘法
{
int tmp[110][110];
mem(tmp,0);
for0(i,n)//不能套三层循环,不然T了
for0(j,n)
tmp[0][i]=(tmp[0][i]+a[0][j]*b[j][i]%M)%M;
for(int i=1;i<n;i++)
for0(j,n)
tmp[i][j]=tmp[i-1][(j-1+n)%n];
for0(i,n)
for0(j,n)
a[i][j]=tmp[i][j];
}
void init()
{
mem(ans,0);
mem(p,0);
for0(i,n)
ans[i][i]=1;
for0(i,n)
p[i][i]=1,p[i][(i+1)%n]=L,p[i][(i+n-1)%n]=R;
}
int main()
{
sf("%d",&t);
while(t--)
{
sf("%d%d%d%d%d",&n,&m,&L,&R,&M);
init();//矩阵初始化
for0(i,n)
sf("%d",&a[i]);
while(m)//矩阵快速幂
{
if(m&1)multi(ans,p);
m>>=1;
multi(p,p);
}
for0(i,n)
{
int o=0;
for0(j,n)
o=(o+ans[i][j]*a[j]%M)%M;
pf(i!=n-1?"%d ":"%d\n",o);
}
}
return 0;
}