题目链接:
题意:
给定
n(1≤n≤500)
个格子,圆排列,规定每次操作将每个格子的值变为到他的距离不超过
d
的所有格子在操作之前的值之和模
分析:
我们发现得到的每次每个元素得到的新值都可以看做是原来值的线性组合,因此可以将各个格子的值表示为列向量,用矩阵乘法来解决。
最初头脑一热写了个矩阵快速幂,发现结构体中的矩阵都开不下= = ,而且时间复杂度
O(n3logk)
也过不了。
仔细观察我们构造的矩阵可以发现从第二行开始每一行都是上一行的循环右移一位的结果,也就是构成了循环矩阵。。
可以发现两个循环矩阵的乘积也是循环矩阵,因此存储时只要保存一行即可,计算时稍加处理也可仅用一行表示,时间复杂度降到
O(n2logk)
,数组也开的下了= =
代码:
/*************************************************************************
> File Name: LA3704.cpp
> Author: jiangyuzhu
> Mail: 834138558@qq.com
> Created Time: 2016/7/27 14:56:56
************************************************************************/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<queue>
#include<cstring>
#include<stack>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 500 + 5;
int mod;
ll a[maxn];
int n, d;
ll k;
const int N = 500 + 5;
struct Matrix
{
int sz;
ll m[N];
};
Matrix init(Matrix a, ll t)
{
for(int i = 0; i < a.sz; i++)
a.m[i] = t;
return a;
}
Matrix operator * (const Matrix& a, const Matrix& bb)
{
Matrix b;b.sz = n;
b = init(b, 0);
for(int i = 0; i < n; i++){
b.m[i] = bb.m[(n - i) % n];
}
Matrix ans;ans.sz = n;
ans = init(ans,0);
for(int j = 0; j < n; j++)
for(int k = 0; k < n; k++)
ans.m[j] = (ans.m[j] + a.m[k] * b.m[((k - j + n)) % n])%mod;
return ans;
}
Matrix mul(Matrix a, Matrix b)
{
Matrix ans;
ans.sz = n;
ans = init(ans,0);
for(int j = 0; j < n; j++)
for(int k = 0; k < n; k++)
ans.m[j] = (ans.m[j] + a.m[(k - j + n) % n] * b.m[k])%mod;
return ans;
}
Matrix quick_pow(ll k, Matrix A)
{
Matrix I;I.sz = n;
I = init(I, 0);
for(int i = 0; i < n; i++){
I.m[i] = a[i];
}
for(; k; k >>= 1, A = A * A){
if(k & 1) I = mul(A, I);
}
return I;
}
int main (void)
{
while(~scanf("%d%d%d%lld", &n, &mod, &d, &k)){
for(int i = 0; i < n; i++){
scanf("%lld", &a[i]);
a[i] %= mod;
}
Matrix A;A.sz = n;A = init(A, 0);
for(int i = 0; i < n; i++){
if(min(n - i, i) <= d) A.m[i] = 1;
}
A = quick_pow(k, A);
for(int i = 0; i < n; i++){
printf("%lld%c", A.m[i], i == n - 1?'\n':' ');
}
}
return 0;
}