列表

详情


NC14549. 布置会场(II)

描述

d接到了一个布置会场的任务。

他需要将贵宾观众席的椅子排成一排,一共需要N个。

上级领导指示,他只能使用两种椅子。(A类型和B类型)并且假设每种椅子的数量都是无限的。

而其如果想要摆置一个B类型的椅子,对应就需要必须有连续两个一起布置。换句话说,就是如果出现了B类型的椅子,其必须且只有两个连着B类型的椅子。

d突然想知道对应N个椅子排成一列,他能够有多少种布置的方式.

输入描述

本题包含多组输入第一行输入一个整数t,表示测试数据的组数
每组测试数据包含一行,输入一个整数N,表示一共需要摆放的椅子数量
t<=1000
1<=N<=100000000000000000(10^18)

输出描述

每组测试数据输出包含一行,表示一共有多少种布置的方式,方案数可能会很大,输出对1000000007取摸的结果。

示例1

输入:

2
2
4

输出:

2
5

说明:

第一个样例,AA,BB两种方案。
第二个样例,AAAA,BBBB,AABB,ABBA,BBAA五种方案 对于ABBB 因为有连续3个B类型椅子所以不可行

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 117ms, 内存消耗: 2724K, 提交时间: 2020-08-05 21:03:02

#include<bits/stdc++.h>
#pragma GCC optimize(3,"Ofast","inline")
#define Fox ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
const int mod=1e9+7;
int T;
long long n;
struct mat{
	int a[3][3];
}u;
mat matmul(mat x,mat y){
	mat tmp;
	for(int i=1;i<3;i++)
		for(int j=1;j<3;j++){
			tmp.a[i][j]=0;
			for(int k=1;k<3;k++)tmp.a[i][j]=(tmp.a[i][j]+1LL*x.a[i][k]*y.a[k][j]%mod)%mod;
		}
	return tmp;
}
void matpow(long long b){
	mat rec=u;
	while(b){
		if(b&1)rec=matmul(rec,u);
		u=matmul(u,u);
		b>>=1;
	}
	cout<<(2LL*rec.a[1][1]%mod+rec.a[1][2])%mod<<"\n";
}
int main(){
	Fox;
	cin>>T;
	while(T--){
		cin>>n;
		if(n<=2){
			cout<<n<<"\n";
			continue;
		}
		u.a[1][1]=u.a[1][2]=u.a[2][1]=1;u.a[2][2]=0;
		matpow(n-3);
	}
	return 0;
}

C++(clang++ 11.0.1) 解法, 执行用时: 261ms, 内存消耗: 1312K, 提交时间: 2023-03-15 09:09:31

#include<bits/stdc++.h>
using namespace std;

#define int long long
const int mod = 1e9 + 7;

pair<int, int> fib(int n) {
    if (n == 0) return {0, 1};
    auto p = fib(n >> 1);
    int c = p.first * (2 * p.second - p.first);
    int d = p.first * p.first + p.second * p.second;
    if (n & 1)
        return {(d % mod + mod) % mod, ((c + d) % mod + mod) % mod};
    else
        return {(c % mod + mod) % mod, (d % mod + mod) % mod};
}

signed main()
{
    int t;
    cin >> t;
    while (t --)
    {
        int n;
        cin >> n;
        cout << fib(n).second << endl;
    }
    return 0;
}

上一题