hdu 5171 GTY'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]

然后写,,,

这个代码有些繁琐,应该把矩阵操作单独写成函数。

日后更新。

代码:

ll const mol = 10000007;

int n,k;
ll ans;
ll matrix[4][4];
int a[100005];

void matrixSolve(int k){ // ¾ØÕóµÄk´Î·½
    if(k==0){
        mem(matrix,0);
        matrix[1][1]=1;
        matrix[2][2]=1;
        matrix[3][3]=1;
        return;
    }
    if(k==1){
        mem(matrix,0);
        matrix[1][1]=matrix[1][2]=matrix[1][3]=1;
        matrix[2][2]=matrix[2][3]=1;
        matrix[3][2]=1;
        return;
    }
    matrixSolve(k/2);
    ll tempMatrix[4][4];
    mem(tempMatrix,0);
    rep(i,1,3){
        rep(j,1,3){
            rep(k,1,3){
                tempMatrix[i][j]=(tempMatrix[i][j]+matrix[i][k]*matrix[k][j]%mol)%mol;
            }
        }
    }
    rep(i,1,3){
        rep(j,1,3){
            matrix[i][j]=tempMatrix[i][j];
        }
    }
    if((k&1)==1){
        ll temp2Matrix[4][4];
        mem(temp2Matrix,0);
        temp2Matrix[1][1]=temp2Matrix[1][2]=temp2Matrix[1][3]=1;
        temp2Matrix[2][2]=temp2Matrix[2][3]=1;
        temp2Matrix[3][2]=1;

        ll temp3Matrix[4][4];
        mem(temp3Matrix,0);
        rep(i,1,3){
            rep(j,1,3){
                rep(k,1,3){
                    temp3Matrix[i][j]=(temp3Matrix[i][j]+tempMatrix[i][k]*temp2Matrix[k][j])%mol;
                }
            }
        }
        rep(i,1,3){
            rep(j,1,3){
                matrix[i][j]=temp3Matrix[i][j];
            }
        }
    }

}

ll solve(int k){ //calc Sk
    ll s2=2,f2=1,f1=1;
    matrixSolve(k-2);
    ll sk=(matrix[1][1]*s2+matrix[1][2]*f2+matrix[1][3]*f1)%mol;
    return sk;
}

int main(){

    while(cin>>n>>k){
        ans=0;
        rep(i,1,n){
            scanf("%d",&a[i]);
            ans=(ans+a[i])%mol;
        }
        sort(a+1,a+1+n);
        if(k==1){
           ans=(ans+a[n-1])%mol;
           ans=(ans+a[n])%mol;
           printf("%I64d\n",ans);
        }
        else{
            int xx=a[n-1];
            int yy=a[n];
            ll ans1=(solve(k)*(ll)xx)%mol;
            ll ans2=((solve(k+1)-1)*(ll)yy)%mol;
            ans=(ans+ans1+ans2)%mol;
            printf("%I64d\n",ans);
        }
    }

    return 0;
}

hdu 5171 GTY's birthday gift(数学,矩阵快速幂)

时间: 2024-10-27 11:46:28

hdu 5171 GTY's birthday gift(数学,矩阵快速幂)的相关文章

HDU 5171 GTY'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

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

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

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

hdu 5171 GTY&#39;s birthday gift (BestCoder Round #29)

GTY's birthday gift                                                                       Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 209    Accepted Submission(s): 71 Problem Description F

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

HDU 4990 Reading comprehension(找规律+矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4990 Problem Description Read the program below carefully then answer the question. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include<iostream> #include

hdu 2604 Queuing dp找规律 然后矩阵快速幂。坑!!

http://acm.hdu.edu.cn/showproblem.php?pid=2604 这题居然O(9 * L)的dp过不了,TLE,  更重要的是找出规律后,O(n)递推也过不了,TLE,一定要矩阵快速幂.然后立马GG. 用2代表m,1代表f.设dp[i][j][k]表示,在第i位,上一位站了的人是j,这一位站的人是k,的合法情况. 递推过去就是,如果j是1,k是2,那么这一位就只能放一个2,这个时猴dp[i][k][2] += dp[i - 1][j][k]; 其他情况分类下就好,然后

HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)

Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 249    Accepted Submission(s): 140 Problem Description Farmer John likes to play mathematics games with his N cows. Recently, t

HDU 5318 The Goddess Of The Moon (矩阵快速幂)

题目链接:HDU 5318 The Goddess Of The Moon 题意:给出N串字符串,若是一个字符串的后缀与另一个字符串的前缀相同并且长度大于1,就表示这两个字符串是可以相连的,问M个字符串相连不同方案数为多少. 思路: 1.将输入的字符串预处理存入一个矩阵中,mp[i][j]=1说明str[i]与str[j]能相连,反之,则不能相连. 2.str[i]与str[j]能相连 转化为 i点到j点可达,那么就可以得到一个有向图,长度为M的意思就是 两点之间所走的步数为M的不同走法有多少种