牛客练习赛87 E.贪吃蛇(构造矩阵快速幂)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客练习赛87 E.贪吃蛇(构造矩阵快速幂)相关的知识,希望对你有一定的参考价值。
考虑刚开局,我们让次大的蛇吃掉最大的蛇,次次大的蛇再吃掉原来次大的蛇…
这样最大蛇长累加到了n-1条蛇上,次大累加到n-2条蛇上…显然这样是最优的
操作一轮过后,原来最小的蛇变成最大的蛇
所以奇数轮我们倒序模拟(因为数组升序),偶数轮我们正序模拟(因为数组降序)
那么由于 m m m的时间可以吃 ⌊ m x ⌋ + 1 \\lfloor \\frac{m}{x} \\rfloor+1 ⌊xm⌋+1次,最后剩下的那条蛇就是答案(因为主角可以开局可以选择任意的蛇)
看起来好像模拟 ⌊ m x ⌋ + 1 \\lfloor \\frac{m}{x} \\rfloor+1 ⌊xm⌋+1次就够了
不过复杂度太高,实际上可以通过矩阵快速幂来巧妙的进行优化
乘完之后T仍然是升序的,操作等价于上面模拟的操作
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10;
const int mod = 1e9+7;
const int N = 59;
int n,x,m,mx,a[maxn];
struct rce
{
int m[N][N];
rce(){ memset( m,0,sizeof m ); }
};
rce operator * ( rce a, rce b )
{
rce ans;
for(int i=1;i<=mx;i++)
for(int j=1;j<=mx;j++)
for(int k=1;k<=mx;k++)
ans.m[i][j] = ( 1ll*ans.m[i][j]+1ll*a.m[i][k]*b.m[k][j]%mod )%mod;
return ans;
}
rce quick(rce x,int n)
{
rce ans = x; n--;
for( ; n ; n>>=1,x=x*x )
if( n&1 ) ans = ans*x;
return ans;
}
int main()
{
int t; cin >> t;
while( t-- )
{
cin >> n >> x >> m; mx = n;
for(int i=1;i<=n;i++) cin >> a[i];
sort( a+1,a+1+n );
rce chu, zhuan;
for(int i=1;i<=n;i++) chu.m[1][i] = a[i];
for(int i=1;i<=n;i++)
{
for(int j=n;j>=n-i+1;j--) zhuan.m[i][j] = 1;
for(int j=n-i;j>=1;j--) zhuan.m[i][j] = 0;
}
chu = chu*quick( zhuan,m/x+1 );
cout << chu.m[1][n] << endl;
}
}
以上是关于牛客练习赛87 E.贪吃蛇(构造矩阵快速幂)的主要内容,如果未能解决你的问题,请参考以下文章
E. Sasha and Array 矩阵快速幂 + 线段树
E. Product Oriented Recurrence(矩阵快速幂+欧拉降幂)