牛客练习赛87 E.贪吃蛇(构造矩阵快速幂)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客练习赛87 E.贪吃蛇(构造矩阵快速幂)相关的知识,希望对你有一定的参考价值。

LINK

考虑刚开局,我们让次大的蛇吃掉最大的蛇,次次大的蛇再吃掉原来次大的蛇…

这样最大蛇长累加到了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.贪吃蛇(构造矩阵快速幂)的主要内容,如果未能解决你的问题,请参考以下文章

纯原生JS面向对象构造函数方法实现贪吃蛇小游戏

E. Sasha and Array 矩阵快速幂 + 线段树

E. Product Oriented Recurrence(矩阵快速幂+欧拉降幂)

Python制作当年第一款手机游戏-贪吃蛇游戏(练习)

CF821 E. Okabe and El Psy Kongroo 矩阵快速幂

JS学习——贪吃蛇代码(简易版)