hdu 5171 fib矩阵快速幂

来源:互联网 发布:unity5.3.4f1破解mac 编辑:程序博客网 时间:2024/04/27 03:56

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5171
题意:
给你N个数字,让你用这些数字构造一个最大的集合,其中可以选取M次最大的俩个数加入集合中,求最后集合中的数最大。
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 .
分析:
k的值辣么大,肯定是快速幂啊!然后就想推个公式,去求解。
显然要保证加入的数最大,必须要让集合中最大的两个相加,设为a,b;然后现在集合中有了一个更大的数c,所以再往集合中加数的时候,要加c,a,现在最大的数是d,再加就是d,c…….规律就是f[n]=f[n-1]+f[n-2],这不就是fib吗!然后化成矩阵的形式,就好了、

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const int mod=10000007;struct Mat{    ll mat[3][3];};Mat mul(Mat a,Mat b){    Mat c; memset(c.mat,0,sizeof(c.mat));    for(int k=0;k<3;k++)        for(int i=0;i<3;i++)        for(int j=0;j<3;j++)        c.mat[i][j]+=(a.mat[i][k]*b.mat[k][j])%mod;    return c;}Mat qmod(Mat a,ll k){    Mat c;    for(int i=0;i<3;i++)        for(int j=0;j<3;j++)        c.mat[i][j]=(i==j);    for(;k;k>>=1){        if(k&1)c=mul(a,c);        a=mul(a,a);    }    return c;}int a[100002];int main(){    int n;ll k;    while(~scanf("%d%I64d",&n,&k)){        ll sum=0;        for(int i=0;i<n;i++)scanf("%d",&a[i]),sum+=a[i];        sort(a,a+n);        Mat c;        c.mat[0][0]=c.mat[0][1]=c.mat[0][2]=1;        c.mat[1][0]=0;c.mat[1][1]=c.mat[1][2]=1;        c.mat[2][0]=0;c.mat[2][1]=1;c.mat[2][2]=0;        Mat ans=qmod(c,k);        int res=(ans.mat[0][0]*sum+ans.mat[0][1]*a[n-1]+ans.mat[0][2]*a[n-2])%mod;        printf("%d\n",res);    }    return 0;}
0 0
原创粉丝点击