牛客练习赛87 E-贪吃蛇(矩阵快速幂)
题面:

题解:
考虑怎么吃最优,设\(l_1<l_2 <l_3.....\) ,那么先\(l_{n-1}\) 吃\(l_n\) , 然后\(l_{n-2}\) 吃\(l_{n-1}\) ,以此类推。
最后形成 \(t1>t2>t3>t4>......\) ,这样吃可以使得所有数都可以增长。
那么一共可以吃 \(m/x+1\) 次,即我们要模板上述过程\(m/x+1\) 次,显然时间复杂度不行
考虑构造一个矩阵:
\[\left[
\begin{matrix}
l_1 & l_2 & l_3 ....\\
\end{matrix} \right]
\times
\left[
\begin{matrix}
0 & 0 & 0 ...&0 &1 \\
0 & 0 & 0 ...&1&1 \\
&&&1&1\\
&0&1&1&1\\
0&1&1&1&1\\
1&1&1&1&1
\end{matrix} \right]
=
\left[
\begin{matrix}
t_1 & t_2 & t_3 ....\\
\end{matrix} \right]
\]
最后利用矩阵快速幂即可。
代码:
#pragma GCC diagnostic error "-std=c++11"
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<ctime>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
const int MAXN=2e5+5;
const int inf=0x3f3f3f3f;
typedef vector<ll> vec;
typedef vector<vec> mat;
ll l[MAXN];
mat mul(mat& A, mat& B)
{
mat C(A.size(), vec(B[0].size()));
for (int i = 0; i < A.size(); i++) {
for (int j = 0; j < B.size(); j++) {
for (int k = 0; k < B[0].size(); k++) {
C[i][k] = (C[i][k] + A[i][j] * B[j][k]%mod) % mod;
}
}
}
return C;
}
mat pow(mat A, ll n)
{
mat B(A.size(), vec(A.size()));
for (int i = 0; i < A.size(); i++) {
B[i][i] = 1;
}
while (n > 0) {
if (n & 1)
B = mul(B, A);
A = mul(A, A);
n >>= 1;
}
return B;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n, x, m;
scanf("%d%d%d", &n, &x, &m);
for (int i = 1; i <= n;i++)
{
scanf("%d", &l[i]);
}
sort(l + 1, l + 1 + n);
m = m / x + 1;
mat A(n, vec(n));
for (int j = 0; j < n;j++)
{
for (int i =0; i < n;i++)
{
if(i<n-j-1)
A[i][j] = 0;
else
A[i][j] = 1;
}
}
cout << m << endl;
A = pow(A, m);
mat B(1, vec(n));
for (int i = 0; i < n;i++)
B[0][i] = l[i+1];
mat ans = mul(B, A);
printf("%lld\n", ans[0][n - 1]);
}
}

浙公网安备 33010602011771号