NC24558. 美丽的字符串
描述
奇奇获得了一个长度为 n 字符串s,该字符串都由 1 组成,也就是说,假如字符串长度 n 为 5,那么 s 为 “11111”。但是奇奇觉得这个字符串太丑了,他决定将这个字符串变得美丽,由于奇奇是个程序员,所以在奇奇的眼中,一个美丽的字符串应该由 0 和 1 组成。更正式的说,在字符串 s 中 0 和 1 的数量都至少有一个。但奇奇不想简单的将 1 变为 0,奇奇想将任意连续的 1 变为 0,我们约定奇奇可以将任意 k 个连续的 1 变成 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 11100C++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); }