首页 > 其他分享 >洛谷 P4910题解

洛谷 P4910题解

时间:2024-08-06 22:06:12浏览次数:16  
标签:arr 洛谷 题解 long 珠子 base pmatrix rst P4910

题目大意

现在穿T次手串,每根手串的长度分别为不同的n,有木和金两种珠子,相邻两颗珠子必须有一个是金。

题目思路分析

我们现在设穿到第n个珠子时用金的方案数为f[1][n],用木的方案数为f[0][n]
如果第n个珠子为金,那么前一颗珠子是什么都可以,因此f[1][n]=f[1][n-1]+f[0][n-1]
而如果第n个珠子为木,那么前一颗珠子必须是金,因此f[0][n]=f[1][n-1]

时间复杂度分析

如果使用纯递推,时间复杂度为O(Tn),如果Tn<=1e8的话,这道题可以轻易解决,然而,这道题n最大能到1e18,而T最大能到10,因此不能使用纯递推
因此需要把时间复杂度优化到O(T\(log_{2}(n)\)),就要用到矩阵加速。
这道题不太方便使用通项公式,因为f[1][n]=f[1][n-1]+f[0][n-1]=f[1][n-1]+f[1][n-2],是一个斐波那契数列,而斐波那契数列的通项公式中有\(\sqrt{5}\)这个无理数,可能会影响计算

所以总体思路就是矩阵快速幂加速递推

代码实现

矩阵乘法中 设A是一个P\(\times\)M,B是一个M\(\times\)Q,C是A乘以B的乘积,那么\(C_{i,j}\)=\(\sum_{k=1}^{M}A_{i,k} \times B_{k,j}\)
利用这个性质,我们可以将递推式转化为

\(\begin{pmatrix}f[0][i]&f[1][i]\end{pmatrix}\times\)

\[\begin{pmatrix} 0 & 1 \\ 1 & 1 \end{pmatrix} \]

$=\begin{pmatrix}f[0][i+1]&f[1][i+1]\end{pmatrix}$
如果第一个用的是木珠子的话,最后一个只能用金珠子,这个要注意一下

AC代码

#include<bits/stdc++.h>
#define N 5
#define mod 1000000007
using namespace std;
long long n;
struct arr{
    long long a[N][N];
    arr(){
        memset(a,0,sizeof(a));
    }
}base,rst;
arr operator *(const arr &a,const arr &b){
    arr rst;
    for(int k=1;k<=N;k++){
        for(int i=1;i<=N;i++){
            for(int j=1;j<=N;j++){
                rst.a[i][j]=(rst.a[i][j]+a.a[i][k]*b.a[k][j]%mod)%mod;
            }
        }
    }
    return rst;
}//矩阵乘法
void qpow(long long b) {
    while (b) {
        if (b & 1) rst = rst * base;
        base = base * base;
        b >>= 1;
    }
}//矩阵快速幂
void func(){
	scanf("%lld",&n);
    rst.a[1][1]=1,base.a[1][1]=rst.a[1][2]=0;//很简单粗暴的初始化
    base.a[1][2]=base.a[2][2]=base.a[2][1]=1;
    qpow(n-1);
    long long ans=rst.a[1][2];
    base.a[1][1]=rst.a[1][1]=0,rst.a[1][2]=1;
    base.a[1][2]=base.a[2][2]=base.a[2][1]=1;
    qpow(n-1);
    ans=(ans+rst.a[1][1]+rst.a[1][2])%mod;
    printf("%lld\n",ans);
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--)func();
}

标签:arr,洛谷,题解,long,珠子,base,pmatrix,rst,P4910
From: https://www.cnblogs.com/wanxue/p/18346078

相关文章

  • 洛谷P5250 【深基17.例5】木材仓库
    【深基17.例5】木材仓库题目描述博艾市有一个木材仓库,里面可以存储各种长度的木材,但是保证没有两个木材的长度是相同的。作为仓库负责人,你有时候会进货,有时候会出货,因此需要维护这个库存。有不超过100000条的操作:进货,格式1Length:在仓库中放入一根长度为Length(不超过\(10......
  • CF573E Bear and Bowling 题解
    Description给定一个长度为\(n\)的序列\(a_{1\dotsn}\)。你要求一个\(a\)的子序列\(b_{1\dotsm}\)(可以为空),使得\(\sum_{i=1}^mib_i\)的值最大。\(n\le10^5\),\(|a_i|\le10^7\)。Solution有一个显然的dp是设\(f_{i,j}\)表示前\(i\)个数,选\(j\)个数的......
  • CF1920D题解
    题面这里不再赘述了,直接搬个链接。InLuoguInCodeforces思路存储一共两种操作:要么在末尾加一个数xxx,要么把整一段复制......
  • NSSCTF靶场题解(6)
    站在小白的视角上,写了在写题目的wp方面更多是想体现题目思考的逻辑和细节,更多是写给同样新手小白的内容,解题方面为什么从这一步到下一步的,很助于培养思考题目的逻辑思维,尽我所能把细节阐释到位,有些地方可能理解说辞不是特别到位,如果有问题就麻烦各位大佬师傅指点~这次题解库收......
  • 题解:CF257C View Angle
    题目传送门题意平面上有\(n\)个点。从原点引出两条射线,将平面分成两个部分,使其中一个部分覆盖所有的点。求这个部分与原点所夹的角的最小度数。思路既然一个部分覆盖了所有的点,那么另一个部分就一个点都没覆盖,那么要让这个部分最优,这两条射线一定经过两个中间没有任何点的点......
  • 【题解】暑假集训CSP提高模拟14
    目录Rank&挂分A.BA题目内容部分分10pts10+20pts正解思路代码B.BB题目内容部分分5pts正解思路代码C.BCD.BDRank&挂分T4暴搜后来改了记搜,不知道哪里锅了,挂5pts。A.BA题目内容现在有\(m\)块烙板,\(n\)张饼,第\(i\)张饼需要烙\(a_i\)个单位时间,一张饼一个单位时刻只能......
  • 2024MX-MF-DAY1-text题解
    T1【题目描述】有\(n\)个人按编号从\(1\)到\(n\)坐成一圈,即第\(i\in[1,n]\)个人右边是\(i+1\),第\(n\)个人右边的人是\(1\)。初始,每个人手上有\(m\)个球。随后,\(n\)个人按编号从小到大的顺序依次执行如下操作:把自己手中的球分成数量相同且尽可能多的三份,......
  • AkSoundSeedAir.dll修复指南:游戏音频问题解决与预防技巧
    AkSoundSeedAir.dll是一个与声音引擎相关的动态链接库(DynamicLinkLibrary,简称DLL)文件,尤其与Wwise(AudiokineticWwise)声音设计和游戏音效中间件有关。Wwise是一个广泛应用于游戏开发的声音引擎,用于处理游戏中的音频和音效,AkSoundSeedAir.dll就是Wwise的一部分,用于实现声音处理......
  • 花园改造 题解
    题目id:9989题目描述小\(X\)开始改造她的环形的花园了,具体来说她要在花园的环上种满\(n\)棵树。她现在有\(3\)种树:种子、小树苗和大树。每个位置上种不同的树会产生不同的满意度,具体来说在第\(i\)个位置,种种子会产生\(a_i\)的满意度,种小树苗会产生\(b_i\)的满意度,种大树会产生\(c......
  • [AGC005B] Minimum Sum 题解
    题目传送门看到这道题很多人用单调栈,其实用笛卡尔树本质差不多,但是思维难度更小。不知道笛卡尔树的同学可以看这里简单说来,笛卡尔树的一个子树可以代表一个区间,且左子树上点的下标小于根节点,右子树上点的坐标大于根节点。这道题要求所有子区间的\(\texttt{min}\)值之和,其实......