• SNOI2017 礼物


    题解

    设前(n)个人的礼物个数和为(F_n), 那么显然$$F_n = 2 imes F_{n-1} + i^k$$
    考虑矩阵快速幂
    棘手的问题是:(i^k)不是可以直接用矩阵乘法可以递推的东西
    由二项式定理可得:$$a^k = sum_{i = 1}{k}(a-1)i {k choose i}$$
    那么我们可以给(left[ (i-1)^0; (i-1)^1;(i-1)^2; cdots; (i-1)^k; ight]) 乘上一个杨辉三角矩阵, 就能得到(left[i^0;i^1;i^2;cdots;i^k ight])
    然后我们就能用矩阵快速幂算(F), 显然(Ans = F_{n-1} + i^k)
    于是就做完了

    注意:这题两个n相乘可能会long long溢出, 因此算(n^k)前要先给(n)取模

    代码

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    
    using namespace std;
    
    
    typedef long long LL;
    
    
    const LL mod = 1e9 + 7;
    
    
    LL power(LL a, LL n, LL mod)
    {
    	LL Ans = 1;
    	
    	while (n)
    	{
    		if (n & 1) Ans = Ans * a % mod;
    		a = a * a % mod;
    		n >>= 1;
    	}
    	
    	return Ans;
    }
    
    
    LL n; int K;
    
    
    struct Matrix
    {
    	LL a[12][12];
    
    	Matrix() { memset(a, 0, sizeof(a)); }
    
    	LL* operator [] (int x) { return a[x]; }
    	
    	friend Matrix operator * (Matrix a, Matrix b)
    	{
    		Matrix Ans;
    		
    		for (int i = 0; i <= K + 1; i++)
    			for (int k = 0; k <= K + 1; k++)
    				if (a[i][k])
    					for (int j = 0; j <= K + 1; j++)
    						(Ans[i][j] += a[i][k] * b[k][j] % mod) %= mod;
    		
    		return Ans;
    	}
    };
    
    Matrix power(Matrix a, LL n)
    {
    	Matrix Ans;
    	for (int i = 0; i <= K + 1; i++) Ans[i][i] = 1;
    	
    	while (n)
    	{
    		if (n & 1) Ans = Ans * a;
    		a = a * a;
    		n >>= 1;
    	}
    	
    	return Ans;
    }
    
    
    Matrix Ans, a;
    
    
    int main()
    {
    	Matrix A, Ans;
    	
    	scanf("%lld %d", &n, &K);
    	
    	if (n <= 2)
    	{
    	    LL Ans = 1;
    	    for (int i = 2; i < n; i++)
    	    	Ans = (2 * Ans + power(i, K, mod)) % mod;
    	    Ans = (Ans + power(n, K, mod)) % mod;
    	    printf("%lld
    ", Ans);
    	    return 0;
    	}
    	
    	A[0][0] = 1;
    	for (int i = 1; i <= K; i++)
    	{
    		A[i][0] = 1; A[i][i] = 1;
    		for (int j = 1; j < i; j++)
    			A[i][j] = (A[i-1][j-1] + A[i-1][j]) % mod;
    	}
    	A[K+1][K+1] = 2;
    	for (int i = 0; i <= K; i++)
    		A[K+1][i] = A[K][i];
    	
    	for (int i = 0; i <= K; i++)
    		Ans[i][1] = 1;
    	Ans[K+1][1] = 1;
    	
    	Ans = power(A, n - 2) * Ans;
    	
    	printf("%lld
    ", (Ans[K+1][1] + power(n%mod, K, mod)) % mod);
    	
    	return 0;
    }
    
  • 相关阅读:
    unity5, Configurable Joint: Anchor, Connected Anchor, Auto Configure Connected Anchor
    unity physics joint
    unity camera aspect
    spineRuntTime for cocos2dx v3,attack播完后回到idle
    spineRunTime for cocos2dx v3 中动画播完删除animation
    spine 2.1.27 Pro 叠加方式(Blending)
    unity5 静态和动态cubmap
    INFINITY的一个坑
    Linux下配置MySQL需要注意的几点
    更换网页tab标题图标
  • 原文地址:https://www.cnblogs.com/2016gdgzoi509/p/11148856.html
Copyright © 2020-2023  润新知