• CSUSTOJ-藤原书记想要探病(简单矩阵快速幂)


    题目连接:http://acm.csust.edu.cn/problem/4044
    CSDN食用链接:https://blog.csdn.net/qq_43906000/article/details/109456571

    Description

    呜呜呜,辉夜大小姐生病了,学生会的三人正在决定由谁去探病,藤原书记知道辉夜大小姐生病后会变的非常可爱,所以她非常想要获得这次探病的机会,于是她提出了一个数学游戏,显然,向白银和石上挑战数学游戏是非常的愚蠢的,但是这次不一样,他找到了秀知院数学第一的你来帮她作弊,这次的游戏的内容和斐波那契数列有关。

    斐波那契数列指的是这样一个数列:(0、1、1、2、3、5、8、13、21、34、……) 在数学上,斐波那契数列以如下被以递推的方法定义:(F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2))

    这次游戏分为两个问题:

    首先给定一个 (n)

    问题一:你要在斐波那契数列中选择任意个不重复的数,使这几个数的和等于 (n) ,如果存在合法的方案,请输出 (Darling) , 否则输出 (o~ha~you)

    问题二:你可以在 (1, 2, 4) 这三个数中每个数选择任意多个,使这些数的和为 (n) ,请计算出有多少种选择的方案数,这个方案数可能很大,请把结果对 (998244353) 取模后输出。注意,数字先后选择顺序不同也代表不同方案数,请看样例解释。

    这对藤原书记来说太难了,所以请你尽快计算出答案,使她可以去探病。

    input

    输入第一行一个整数(T)表示数据组数。

    接下来(T)行每行一个整数表示(n)

    (1le Tle 20, 1le nle 10000000000)

    output

    每组数据都输出(2)行,表示两个问题的答案。

    Sample Input 1
    2
    2
    4
    Sample Output 1
    Darling
    2
    Darling
    6

    Hint

    对于第一组数据:

    第一个问题,PPH直接跳一步且步长为(2)米即可。

    第二个问题,PPH有两种方案:({1,1},{2})

    对于第二组数据:

    第一个问题,PPH先跳一步且步长为(1)米,再跳一步步长为(3)米即可。

    第二个问题,PPH有六种方案:({1,1,1,1},{1,1,2},{1,2,1},{2,2},{2,1,1},{4})

    emmm,刚开始的时候看到这题还感觉出的太简单了,这不是送分嘛。。。后来瞄了一眼数据范围,emmm,挺好的,加了个算法,虽然挺裸的,但没学过还真不知道怎么搞。

    首先暴力的写法很简单,就是一个递推式子:(dp[i]=dp[i-1]+dp[i-2]+dp[i-4]),对于第一问其实我们可以直接得出Darling,因为所有的整数都可以用斐波那契数列来表示的,所以并不会有什么no的方案。

    这题关键的地方在于求解方案数,也就是第二问。我们知道快速求一个递推式可以使用矩阵来加速它,那么直接上手就完事了。由于递推式中有到i-4这里,所以我们需要用到4维矩阵,那么也就是构建一个方阵A使得
    (Acdot egin{pmatrix} f_{n-1}\f_{n-2} \ f_{n-3} \ f_{n-4} end{pmatrix}=egin{pmatrix} f_n\ f_{n-1} \ f_{n-2} \ f_{n-3} end{pmatrix})
    那么我们很容易得到
    (A=egin{pmatrix} 1 & 1 & 0 & 1\ 1 & 0 & 0 & 0\ 0 & 1 & 0 & 0\ 0 & 0 & 1 & 0 end{pmatrix})

    于是矩阵快速幂写一写,实际上也就是个普通的快速幂加上一个矩阵乘法而已。

    以下是AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int mod=998244353;
    
    struct Mat
    {
    	ll mat[5][5];
    	Mat(){memset(mat,0,sizeof mat);}
    };
    ll dp[6];
    
    Mat mult(Mat a,Mat b)
    {
    	Mat ans;
    	for (int i=1; i<=4; i++)
    		for (int j=1; j<=4; j++)
    			for (int k=1; k<=4; k++)
    				ans.mat[i][j]=(ans.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod;
    	return ans;
    }
    
    Mat qick(Mat a,ll b)
    {
    	Mat ans;
    	ans.mat[1][1]=ans.mat[2][2]=ans.mat[3][3]=ans.mat[4][4]=1;
    	while (b){
    		if (b&1) ans=mult(ans,a);
    		b>>=1;
    		a=mult(a,a);
    	}
    	return ans;
    }
    
    int main(int argc, char const *argv[])
    {
    	int t;
    	dp[1]=1; dp[2]=2; dp[3]=3; dp[4]=6;
    	scanf ("%d",&t);
    	while (t--){
    		ll n;
    		scanf ("%lld",&n);
    		printf ("Darling
    ");
    		if (n<=4) {printf ("%lld
    ",dp[n]); continue;}
    		Mat a;
    		a.mat[1][1]=a.mat[1][2]=a.mat[1][4]=1;
    		a.mat[2][1]=a.mat[3][2]=a.mat[4][3]=1;
    		Mat ans=qick(a,n-4);
    		Mat base;
    		base.mat[1][1]=dp[4]; base.mat[2][1]=dp[3]; 
    		base.mat[3][1]=dp[2]; base.mat[4][1]=dp[1];
    		ans=mult(ans,base);
    		printf("%lld
    ",ans.mat[1][1]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    团队项目总结
    CVPR顶会论文爬取存入MySQL数据库(标题、摘要、作者、PDF链接和原地址)
    如何做好招聘----CEO如何识别优秀的候选人
    《产品方法论 俞军》 读书笔记总结--2021年的第41/100本
    《增长黑客 sean ellis》 读书笔记总结--2021年的第40/100本
    《参与感 黎万强》 读书笔记总结--2021年的第37/100本
    《领导梯队 拉姆查兰》 读书笔记总结--2021年的第35/100本
    《一本书读懂财报》 读书笔记总结--2021年的第34/100本
    《OKR工作法 克里斯蒂娜沃尔克》精读 读书笔记总结----《创业必读书第13本》--创业第三关做好业务:1.如何做好组织管理的第2本
    《美学思维》 混沌大学商学院第12章 读书笔记总结--2020年的第28/100本
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13941879.html
Copyright © 2020-2023  润新知