HDU5171 GTY's birthday gift(矩阵快速幂)

Problem Description

FFZ‘s birthday is coming. GTY wants to give a gift to ZZF. He asked his gay friends what he should give to ZZF. One of them said, ‘Nothing is more interesting than a number multiset.‘ So GTY decided to make a multiset for ZZF. Multiset
can contain elements with same values. Because GTY wants to finish the gift as soon as possible, he will use JURUO magic. It allows him to choose two numbers a and b(a,b∈S),
and add a+b
to the multiset. GTY can use the magic for k times, and he wants the sum of the multiset is maximum, because the larger the sum is, the happier FFZ will be. You need to help him calculate the maximum sum of the multiset.

Input

Multi test cases (about 3) . The first line contains two integers n and k (2≤n≤100000,1≤k≤1000000000).
The second line contains n elements ai
(1≤ai≤100000)separated
by spaces , indicating the multiset S .

Output

For each case , print the maximum sum of the multiset (mod 10000007).

Sample Input

3 2
3 6 2

Sample Output

35

Source

BestCoder Round #29

Recommend

参考大神博客 :http://blog.csdn.net/crescent__moon/article/details/43617703

//需要知道的一点是斐波拉契数列  s(n)=a(n+2)-1;

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>

using namespace std;

#define mod 10000007

#define N 100005

typedef __int64 ll;

struct mat{
    ll a[2][2];
    mat(){memset(a,0,sizeof(a));}

    mat operator *(mat b)
    {
    	mat c;
        for(int i=0;i<2;i++)
		  for(int j=0;j<2;j++)
		{
			c.a[i][j]=0;
			for(int k=0;k<2;k++)
				c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j]%mod)%mod;
		}
		return c;
    }

};

ll ans;
int a[N];
mat s,e;

void inint()
{
 	s.a[0][0]=s.a[0][1]=s.a[1][0]=1;
 	s.a[1][1]=0;

 	int i,j;
 	e.a[0][1]=e.a[1][0]=0;
 	for(i=0;i<2;i++)
		e.a[i][i]=1;
}

mat powmul(int k)
{
    int i,j;
    while(k)
	{
		if(k&1)
		{
			e=e*s;
		}
		k>>=1;
		s=s*s;
	}
	return e;
}

int main()
{
	int i,j;
	ll k,n;
	while(~scanf("%I64d%I64d",&n,&k))
	{
		ans=0;
		for(i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
			ans=(ans+a[i])%mod;
		}

		inint();
		sort(a,a+n);

		s=powmul(k+2);

		ans=(ans+(s.a[0][0]-2)*a[n-1]%mod)%mod; //好好看看上面的话,列出数列

		ans=(ans+(s.a[0][1]-1)*a[n-2]%mod)%mod;

		printf("%I64d\n",ans);

	}
	return 0;
}

HDU5171 GTY's birthday gift(矩阵快速幂)

时间: 2024-10-12 21:04:58

HDU5171 GTY's birthday gift(矩阵快速幂)的相关文章

HDU 5171 GTY&#39;s birthday gift 矩阵快速幂

点击打开链接 GTY's birthday gift Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 225    Accepted Submission(s): 78 Problem Description FFZ's birthday is coming. GTY wants to give a gift to ZZF. He as

【Best Coder】#29 B GTY&#39;s birthday gift(快速幂|mod的时候记得负!)

题目大意:查看相关场次即可看到. 思路:推公式的题目,可以用快速幂加公式快速解决,也可以用二进制拆分运算的方法加快速度. 需要注意的一点在于:今后在mod之后有涉及到运算的都要加上一个mod之后再mod,或者统一都加一个mod 顺便复习一下二进制拆分的方法!! 二进制拆分的做法AC代码: #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<cstdio> usin

HDU 5171 GTY&#39;s birthday gift(矩阵快速幂 )

HDU 5171 GTY's birthday gift ( 矩阵快速幂裸题目 ) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAX_SIZE 3 #define MOD 10000007 #define clr( a, b ) memset( a, b, sizeof(a) ) typedef long long LL; struct M

hdu 5171 GTY&#39;s birthday gift(数学,矩阵快速幂)

题意: 开始时集合中有n个数. 现在要进行k次操作. 每次操作:从集合中挑最大的两个数a,b进行相加,得到的数添加进集合中. 以此反复k次. 问最后集合中所有数的和是多少. (2≤n≤100000,1≤k≤1000000000) 思路: 写出来发现是要求Fibonaci的前n个数的和. Fibonaci是用矩阵快速幂求的,这个也可以. [Sn,Fn,Fn-1]=[某个矩阵]*[Sn-1,Fn-1,Fn-2] [S2,F2,F1]=[2,1,1] 然后写,,, 这个代码有些繁琐,应该把矩阵操作单独

GTY&#39;s birthday gift【矩阵快速幂】

题目大意:GTY的朋友ZZF的生日要来了,GTY问他的基友送什么礼物比较好,他的一个基友说送一个可重集吧!于是GTY找到了一个可重集S,GTY能使用神犇魔法k次,每次可以向可重集中加入一个数 a+b ,现在GTY想最大化可重集的和,这个工作就交给你了. 注:可重集是指可以包含多个相同元素的集合 思路:这题 呵呵呵,太伤心 不想写思路 #include<iostream>#include<cstdio>#include <math.h>#include<algori

hdu5171(矩阵快速幂)

传送门:GTY's birthday gift 题意:GTY的朋友ZZF的生日要来了,GTY问他的基友送什么礼物比较好,他的一个基友说送一个可重集吧!于是GTY找到了一个可重集S,GTY能使用神犇魔法k次,每次可以向可重集中加入一个数 a+b(a,b∈S),现在GTY想最大化可重集的和,这个工作就交给你了. 注:可重集是指可以包含多个相同元素的集合 分析:想要和最大,那么每次必定从集合里面拿出最大的两个出来相加,然后k次后面就类似斐波那契数列了. 由斐波那契数列公式知:Fn=Fn-1+Fn-2,

BestCoder Round #29——A--GTY&#39;s math problem(快速幂(对数法))、B--GTY&#39;s birthday gift(矩阵快速幂)

GTY's math problem Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description GTY is a GodBull who will get an Au in NOI . To have more time to learn alg

HDU5171 矩阵快速幂

题目描述:http://acm.hdu.edu.cn/showproblem.php?pid=5171 算法: 可以先将数组a[]排序,然后序列 a1 , a2 , … , an 即为有序序列,则第一次加入的就是 an + an-1 ,第二次就是 an + (an + an-1) ,如此循环就构成了斐波那契序列. 设斐波那契序列的第k项为Fk,则可知第k次加入的即为 Fk+1 * an +  Fk * an-1 设斐波那契序列的前k项和为Sk, 则所得结果res即为:a1 + a2 + … +

HUST 1569(Burnside定理+容斥+数位dp+矩阵快速幂)

传送门:Gift 题意:由n(n<=1e9)个珍珠构成的项链,珍珠包含幸运数字(有且仅由4或7组成),取区间[L,R]内的数字,相邻的数字不能相同,且旋转得到的相同的数列为一种,为最终能构成多少种项链. 分析:这是我做过的最为综合的一道题目(太渣了),首先数位dp筛选出区间[L,R]内的幸运数字总数,dp[pos]表示非限制条件下还有pos位含有的幸运数字个数,然后记忆化搜索一下,随便乱搞的(直接dfs不知会不会超时,本人做法900+ms险过,应该直接dfs会超时),再不考虑旋转相同的情况,可以