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

来源:互联网 发布:数据建模是什么 编辑:程序博客网 时间:2024/05/01 09:39

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5171

题意:给定一个数列,要求不断的取最大和次大的两个数字的和加入原数列,重复该操作k次,问最终数列的和是多少

思路:由于k很大,如果直接不停地累加、更新,会超时,这样就用到了快速幂,每次的和sum更新为sum+最大+次大,最大的数更新为原来最大+原来次大,次大的数更新为原来的最大,所以用一个3*3的矩阵表示这个三个数字({1,1,1},{0,1,1},{0,1,0})累乘k次,最后分别乘原来的sum,最大,次大,代码如下

代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cctype>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
#define debug "output for debug\n"
#define pi (acos(-1.0))
#define eps (1e-8)
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
const int maxn = 100005;
#define mod 10000007
struct matrix
{
    ll m[3][3];
};
matrix mul(matrix x, matrix y)
{
    matrix temp;
    memset(temp.m, 0, sizeof(temp.m));
    int i, j, k;
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 3; j++)
        {
            if (x.m[i][j] == 0)
            {
                continue;
            }
            for (k = 0; k < 3; k++)
            {
                if (y.m[j][k] == 0)
                {
                    continue;
                }
                temp.m[i][k] = (temp.m[i][k] + (x.m[i][j] * y.m[j][k]) % mod) % mod;
            }
        }
    }


    return temp;
}
matrix quickpow(matrix a, int n)
{
    matrix res;
    memset(res.m, 0, sizeof(res.m));
    for (int i = 0; i < 3; i++)
    {
        res.m[i][i] = 1;
    }
    while (n)
    {
        if (n & 1)
        {
            res = mul(res,a);
        }
        n >>= 1;
        a = mul(a, a);


    }
    return res;
}
int main()
{
    int n,k;
    int a[maxn];
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        ll sum=0;
        for(int i=0; i<n; i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i];


        }
        sort(a,a+n);
        //cout<<m1<<" "<<m2<<endl;
        matrix y,aa,x;
        aa.m[0][0]=1;
        aa.m[0][1]=1;
        aa.m[0][2]=1;
        aa.m[1][0]=0;
        aa.m[1][1]=1;
        aa.m[1][2]=1;
        aa.m[2][0]=0;
        aa.m[2][1]=1;
        aa.m[2][2]=0;
        y = quickpow(aa,k);
        printf("%lld\n", (y.m[0][0] * sum + y.m[0][1] *a[n-1] + y.m[0][2] * a[n-2]) % mod);
    }
return 0;
}

0 0
原创粉丝点击