列表

详情


NC24558. 美丽的字符串

描述

奇奇获得了一个长度为 字符串s,该字符串都由 组成,也就是说,假如字符串长度 为 5,那么 为 “11111”。但是奇奇觉得这个字符串太丑了,他决定将这个字符串变得美丽,由于奇奇是个程序员,所以在奇奇的眼中,一个美丽的字符串应该由 和 组成。更正式的说,在字符串 中 和 的数量都至少有一个。但奇奇不想简单的将 变为 0,奇奇想将任意连续的 变为 0,我们约定奇奇可以将任意 个连续的 变成 0,求奇奇将字符串变得美丽的不同方案数。(两个方案定义为不同,意味着他们最后所形成的字符串不相同)由于可能有太多的方案,你只需要求出方案数模1000000007

输入描述

第一行输入两个整数n, k (1<=n<=1*1018, 2 <= k<= 100) n为

字符串长度,长度为k的连续的1可以变为0。

输出描述

方案数模1000000007

示例1

输入:

4 2

输出:

3

说明:

0011 1001 1100 共三种

示例2

输入:

5 2

输出:

7

说明:

00111 10011 11001 11100

00001 00100 10000 共七种

原站题解

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

C++14(g++5.4) 解法, 执行用时: 153ms, 内存消耗: 736K, 提交时间: 2019-04-15 00:32:40

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int mod = 1e9+7;
LL n,k,a[110][110],b[110][1],dp[110];
void init(){
    a[0][0] = a[0][k-1] = 1,dp[0] = 1;
    for(int i = 1;i <= k; ++i) dp[i] = (dp[i-1] + (i-k >= 0 ? dp[i-k] : 0))%mod;
    for(int i = 1;i < k; ++i) a[i][i-1] = 1;
    for(int i = 0; i < k ; ++i) b[i][0] = dp[k-i];
}
void calmatrix1(){
    LL c[110][1] = {0};
    for(int i = 0;i < k; ++i)
        for(int j = 0;j < k; ++j)
            c[i][0] = (c[i][0] + a[i][j]*b[j][0]) % mod;
    memcpy(b,c,sizeof(c));
}
void calmatrix2(){
    LL c[110][110] = {0};
    for(int i = 0;i < k; ++i)
        for(int j = 0;j < k; ++j)
            for(int t = 0;t < k; ++t)
                c[i][t] = (c[i][t] + a[i][j]*a[j][t]) % mod;
    memcpy(a,c,sizeof(c));
}
LL solve(LL x)
{
    init();
    while(x){
        if(x & 1) calmatrix1();
        calmatrix2();
        x >>= 1;
    }
    return b[k-1][0];
}
int main()
{
    cin >> n >> k;
    if(n <= k) cout << 0 << '\n';
    else cout << (solve(n-1) - 2 + ((n%k)?1:0) + mod) % mod << '\n';
    return 0; 
}

C++11(clang++ 3.9) 解法, 执行用时: 2549ms, 内存消耗: 744K, 提交时间: 2019-04-13 17:38:07

#include<cstdio>
long long mo=1000000007;
long long n,x1,Pow,q[105][105],a[105][105],res[105][105],E[105][105],ans;
int main()
{
	scanf("%lld%lld",&n,&x1);
	a[1][1]=a[1][x1]=1;
	for(int i=1;i<x1;i++)
		a[i+1][i]=1;
	for(int i=1;i<=x1;i++)
		for(int j=1;j<=x1;j++)
		{
			q[i][j]=a[i][j];
			res[i][i]=1;
		}
	Pow=n-x1+1;
	while(Pow)
	{
		if(Pow&1)
		{
			for(int i=1;i<=x1;i++)
				for(int j=1;j<=x1;j++)
					for(int k=1;k<=x1;k++)
						E[i][j]=(E[i][j]+(q[i][k]*res[k][j])%mo)%mo;
			for(int i=1;i<=x1;i++)
				for(int j=1;j<=x1;j++)
				{
					res[i][j]=E[i][j];
					E[i][j]=0;
				}
		}
		for(int i=1;i<=x1;i++)
			for(int j=1;j<=x1;j++)
				for(int k=1;k<=x1;k++)
					E[i][j]=((q[i][k]*q[k][j])%mo+E[i][j])%mo;
		for(int i=1;i<=x1;i++)
			for(int j=1;j<=x1;j++)
			{
				q[i][j]=E[i][j];
				E[i][j]=0;
			}
		Pow/=2;
	}
	for(int i=1;i<=x1;i++)
		ans=(ans+res[i][1])%mo;
	ans=ans-1-(n%x1==0);
	if(ans<0) ans+=mo;
	printf("%lld",ans);
}

上一题