• 【BZOJ5015】[Snoi2017]礼物 矩阵乘法


    【BZOJ5015】[Snoi2017]礼物

    Description

    热情好客的请森林中的朋友们吃饭,他的朋友被编号为 1~N,每个到来的朋友都会带给他一些礼物:。其中,第一个朋友会带给他 1 个,之后,每一个朋友到来以后,都会带给他之前所有人带来的礼物个数再加他的编号的 K 次方那么多个。所以,假设 K=2,前几位朋友带来的礼物个数分别是:1,5,15,37,83假设 K=3,前几位朋友带来的礼物个数分别是:1,9,37,111现在,好奇自己到底能收到第 N 个朋友多少礼物,因此拜托于你了。已知 N,K请输出第 N 个朋友送的礼物个数 mod1000000007。

    Input

    第一行,两个整数 N,K
    N≤10^18,K≤10

    Output

    一个整数,表示第 N 个朋友送的礼物个数 mod1000000007。 

    Sample Input

    4 2

    Sample Output

    37

    题解:一开始想到$1^d+2^d+...+n^d$是一个d+1次的多项式,所以猜想它的前缀和也是一个多项式,后来实验了一下死活试不出来。于是换个思路想矩乘,倒是一下就想出来了。。。

    我们用S[i]表示$sumlimits_{i=1}^nsumlimits_{j=1}^ij^k=sumlimits_{i=1}^ni^k(n-i+1)$,那么ans=S[n]-S[n-1],所以维护以下行向量:

    $egin{pmatrix}i^0 & i^1 & ... & i^k & S[i] $

    如何得到i^k呢?用$(i-1)^0,(i-1)^1,...(i-1)^k$乘上组合数即可。如何得到S[i]呢?用$2*S[i-1]+i^k$即可。然后就没了。

     

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    const ll P=1000000007;
    ll n;
    ll c[20][20];
    int m;
    struct M
    {
    	ll a[20][20];
    	M () {memset(a,0,sizeof(a));}
    	ll * operator [] (int b){return a[b];}
    	M operator * (M b)
    	{
    		M c;
    		int i,j,k;
    		for(i=0;i<=m+1;i++)	for(j=0;j<=m+1;j++)	for(k=0;k<=m+1;k++)	c[i][j]=(c[i][j]+a[i][k]*b[k][j])%P;
    		return c;
    	}
    }tr,a1,a2;
    M pm(M ret,ll y)
    {
    	M x=tr;
    	while(y)
    	{
    		if(y&1)	ret=ret*x;
    		x=x*x,y>>=1;
    	}
    	return ret;
    }
    int main()
    {
    	scanf("%lld%d",&n,&m);
    	int i,j;
    	c[0][0]=1;
    	for(i=1;i<=m;i++)
    	{
    		c[i][0]=1;
    		for(j=1;j<=i;j++)	c[i][j]=(c[i-1][j-1]+c[i-1][j])%P;
    	}
    	for(i=0;i<=m;i++)
    	{
    		a1[0][i]=a2[0][i]=1;
    		for(j=0;j<=i;j++)	tr[j][i]=c[i][j];
    	}
    	tr[m+1][m+1]=2,tr[m][m+1]=1;
    	a1=pm(a1,n-1),a2=pm(a2,n);
    	printf("%lld",(a2[0][m+1]-a1[0][m+1]+P)%P);
    	return 0;
    }

     

  • 相关阅读:
    leetcode[45]Jump Game II
    leetcode[46]Permutations
    leetcode[47]Permutations II
    leetcode[48]Rotate Image
    手把手一起玩perl安装
    List the Modules in Your System
    oracle之recyclebin
    10g 11g新特性
    RMAN相关操作命令
    手把手一起安装RAC+DataGuard
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7500294.html
Copyright © 2020-2023  润新知