【校内模拟】数列
![](https://img2018.cnblogs.com/blog/1340330/201810/1340330-20181019080446315-1580382296.png)
这是一套模拟题的\(T1\)
看完题我首先想到的是找规律
我人工推了几项后发现了一点鬼畜的规律,然后就打了代码
直到爆零之后发现它不是一道找规律的题
看完题解我感觉无\(F**K\)说
为什么\(T1\)如此毒瘤(其实是我太菜)
题解:
显然根据斐波那契数列,第\(50\)个字符串的长度一定远超过了\(2^{31}\)的范围
我们不妨将大于\(50\)的\(n\) 奇数看作\(49\),偶数看作\(48\)
我们可以将前\(20\)个字符串预处理出来
当\(n\leq 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;
}