题目链接:acm.fzu.edu.cn/problem.php?pid=1692
题目的意思比较简单。。。
说是,n个小孩围成一圈。。。。(n最大100)。。初始时,每个小孩有ai个苹果。。对于每轮游戏,第i个小孩可以再获得他左边的L倍 + 他右边的 R倍个苹果。。。。问m轮游戏以后。。每个小孩有多少个苹果。。。最后mod一个数。。(m <= 10^9)。。。。
一直推样例。。。没过。。。。。样例都推不出来。。。囧。。。
后来试试 他左边的R倍 + 右边的L倍。。。。样例出来了。。。你逗我们呢???好吧。。.
矩阵快速幂。。。。。。。。。这是一开始的想法。。。水之????
果断的TLE了。。。。。。- - 。。0.0 还有更加优化的方法???好吧。。又 学习了。。。
学习了一种特殊矩阵乘法的n^2复杂度。。。
比如这个问题。。。
我们可以构造出状态转移矩阵。。。很easy。。。。。。
比如 n = 5的时候。。我们的状态转移矩阵为:
A = {
1 R 0 0 L
L 1 R 0 0
0 L 1 R 0
0 0 L 1 R
R 0 0 L 1
};
这是我们的状态转移矩阵。。。。。。。。。
我们可以发现
A^2 = {
2RL 2R R^2 L^2 2L
2L 2RL 2R R^2 L^2
L^2 2L 2RL 2R R^2
R^2 L^2 2L 2RL 2R
2R R^2 L^2 2L 2RL
};
也就是说,我们可以通过推出第一层。。。。然后从第一层推出第二层。。。。。这样就可以为n^2的时间复杂度了求出矩阵乘法了。。。。比较特殊的是,这种做法,只能用于这种特殊的矩阵。。。。所以,对于广泛性上,还需要很大的提高。。。!!
Code:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdio>
using namespace std;
#define LL long long
const int N = 105;
LL n, m, L, R, mod;
LL a[N];
struct Matrix
{
int n, m;
LL mi[N][N];
void CLR(){
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++)
mi[i][j] = 0;
}
}
void Unit(){
for(int i = 1; i <= n; i ++){
mi[i][i] = 1;
}
}
} A, ans;
Matrix operator * (Matrix a, Matrix b)
{
Matrix tmpans;
tmpans.n = a.n; tmpans.m = b.m;
tmpans.CLR();
for(int i = 1; i <= a.m; i ++){
for(int j = 1; j <= b.n; j ++)
tmpans.mi[1][i] = (tmpans.mi[1][i] + a.mi[1][j] * b.mi[j][i]) % mod;
}
for(int i = 2; i <= a.n; i ++){
tmpans.mi[i][1] = tmpans.mi[i - 1][a.n];
for(int j = 2; j <= b.n; j ++){
tmpans.mi[i][j] = tmpans.mi[i - 1][j - 1];
}
}
return tmpans;
}
void power(LL k)
{
while(k){
if(k & 1) ans = ans * A;
A = A * A;
k = k >> 1;
}
}
int main()
{
// freopen("1.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T --){
scanf("%I64d %I64d %I64d %I64d %I64d", &n, &m, &L, &R, &mod);
ans.n = 1; ans.m = n;
for(int i = 1; i <= n; i ++){
scanf("%I64d", &ans.mi[1][i]);
}
A.n = n; A.m = n;
A.CLR();
A.mi[n][1] = R;
for(int i = 1; i <= n; i ++){
A.mi[i - 1][i] = R;
A.mi[i][i] = 1;
A.mi[i + 1][i] = L;
}
A.mi[1][n] = L;
power(m);
for(int i = 1; i <= n; i ++){
printf("%I64d%c", ans.mi[1][i] % mod, i == n ? '\n' : ' ');
}
}
return 0;
}
表示,又长知识了。。。