这是一套模拟题的(T1)
看完题我首先想到的是找规律
我人工推了几项后发现了一点鬼畜的规律,然后就打了代码
直到爆零之后发现它不是一道找规律的题
看完题解我感觉无(F**K)说
为什么(T1)如此毒瘤(其实是我太菜)
题解:
显然根据斐波那契数列,第(50)个字符串的长度一定远超过了(2^{31})的范围
我们不妨将大于(50)的(n) 奇数看作(49),偶数看作(48)
我们可以将前(20)个字符串预处理出来
当(nleq 20)时直接输出答案
否则设一个函数(solve(n,l,r))递归到(n-2)和(n-1)
(l),(r)的递归需要知道第(n-2)个字符串的长度
预处理斐波那契数列即可
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define LL long long
int n,l,r;
LL f[50];
string s[21];
void solve(int t,int x,int y){
if(x>y||x>=f[t]) return;
if(t<=20){
for(int i=x;i<=y;++i)
putchar(s[t][i]);
return;
}
if(f[t-2]-1>=y)
solve(t-2,x,y);
else if(f[t-2]<=x)
solve(t-1,x-f[t-2],y-f[t-2]);
else {
solve(t-2,x,f[t-2]-1);
solve(t-1,0,y-f[t-2]);
}
}
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%d%d%d",&n,&l,&r);
if(n>=50)
if(n%2) n=49;
else n=48;
f[0]=1;
f[1]=1;
for(int i=2;i<=n;++i)
f[i]=f[i-1]+f[i-2];
s[0]="0";
s[1]="1";
for(int i=2;i<=20;++i)
s[i]=s[i-2]+s[i-1];
if(n<=20){
for(int i=l;i<=r;++i)
putchar(s[n][i]);
puts("");
return 0;
}
solve(n,l,r);
fclose(stdin); fclose(stdout);
return 0;
}