题解 P4910 【帕秋莉的手环】

对于这道题,我第一眼竟然是去看标签,然后跟着标签推思路
题目很长,我在这就不赘述了。

简单理解,就是给定一个 n,条件是长度为n的一串 01 (我们将木属性定为 0 ,金属性定为 1) 数列中不能有连续的两个 0,因为又是环,所以当数列的首位中有一个为 0 的话,另一个就不能为 0,求满足条件的长度为 n 的数列有多少种,答案对 1000000007 取模。

说实话,我没看懂样例解释。 但并不妨碍我们去分析题目。

当 n = 1 时 只有 1 这一种情况。

当 n = 2 时 有 10 11 01 三种情况。

现在,我们以 n = 1 和 n = 2 为基础,往后进行推测。

当 n = 3 时

当首位为 0 时,只有 011 一种情况。
当首位为 1 时 有 111 101 110 三种情况。

共四种情况

当 n = 4 时

当前两位为 10 时 后面可接 10 11 两种情况。
当前两位为 11 时 后面可接 10 11 01 三种情况。
当前两位为 01 时 后面可接 11 01 两种情况。

共七种情况

同理,当 n = 5 时,对首位和倒数第二位进行分类讨论

当首位为 1 时
	倒数第二位为 1 时 可接 1 0 。
	倒数第二位为 0 时 可接 1 。
当首位为 0 时
	倒数第二位为 1 时 可接 1 。
	倒数第二位为 0 时 可接 1 。

再根据 n = 4 时的七种情况,可推出共有十一种情况

现在我们再回头看,可以发现

n [ 3 ] = n [ 2 ] + n [ 1 ]

n [ 4 ] = n [ 3 ] + n [ 2 ]

n [ 5 ] = n [ 4 ] + n [ 3 ]

这不就是斐波那契数列嘛

既然我们已经推出了这道题的核心思想,那么剩下的就很好解决了。

但要注意 1 ≤ n ≤ 10^18 ,正常的递推肯定会超时,所以我们需要用矩阵快速幂来加速,如果还不知道的建议先去了解这道题 斐波那契数列

附上代码

#include<bits/stdc++.h>
#define ll long long
const int mod=1e9+7;
using namespace std;
struct miku{
  ll a[3][3];
  miku()
  {
  	memset(a,0,sizeof(a));
  }
}MIKU,IA;//矩阵
miku operator *(const miku &x,const miku &y)//重载运算符
{
  miku z;
  for(int k=1;k<=2;k++)
  	for(int i=1;i<=2;i++)
  		for(int j=1;j<=2;j++)
  			z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
  return z;
}
void Vocaloid()
{
  MIKU.a[1][1]=3,MIKU.a[1][2]=1;
  MIKU.a[2][1]=0,MIKU.a[2][2]=0;
  IA.a[1][1]=1,IA.a[1][2]=1,IA.a[2][1]=1,IA.a[2][2]=0;
}//初始矩阵的赋值
ll read()//快读
{
  long long x=0,flag=1;char ch=getchar();
  while(!isdigit(ch)) {if(ch=='-') flag=-1;ch=getchar();}
  while(isdigit(ch)) {x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
  return x*flag;
}
int T;
ll n;
int main()
{
  scanf("%d",&T);
  while(T--)
  {
  	n=read();
  	Vocaloid();
  	miku ans=MIKU;
  	if(n<=2)//特判一下,当 n ≤ 2 时,直接输出
  	{
  		if(n==1) puts("1");
  		else if(n==2) puts("3");
  		continue ;	
  	} 
  	n-=2;
  	do
  	{
  		if(n&1) ans=ans*IA;
  		IA=IA*IA;
  		n>>=1;
  	}while(n);
  	printf("%d
",ans.a[1][1]%mod);
  }
  return 0;
}

PS:

其实此题和这道题和像 单词

如果有什么问题可以在评论区提出,我会尽己所能去回答的 (毕竟我也才学信息没多久)

这是本人的第一篇题解,如果有什么问题还请管理员大大提出,我会加以改正 QAQ 。

原文地址:https://www.cnblogs.com/MIKU5201314/p/13525389.html