链接:https://ac.nowcoder.com/acm/contest/911/E
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
str1,str2为给定的字符串,定义 F[1] = str1, F[2] = str2,F[i]=F[i-1]+F[i-2],其中 "+" 表示字符串拼接,字符串由小写英文字母组成。多组查询,每组查询输入 x,y,输出F[x]的第 y 位,x,y≤1018x,y≤1018(下标从 1 开始)。
输入描述:
第一行两个字符串表示 str1,str2(1≤|str1|,|str2|≤50)str1,str2(1≤|str1|,|str2|≤50),第 3 行一个整数 Q(Q≤100000Q≤100000),接下来 Q 行,Q 组查询。每组查询两个数字 x,y(x,y≤1018,y≤|F(x)|)x,y(x,y≤1018,y≤|F(x)|)
(注:对于一个字符串 str,|str| 表示字符串 str 的长度。)
输出描述:
输出 Q 行,每组查询输出一个字符,表示答案。
示例1
输入
a b 4 1 1 2 1 3 2 4 3
输出
a b a b
备注:
样例解释 F[1]="a", F[2]="b", F[3]="ba", F[4]="bab"
只要我们手打出几项我们就很容易发现规律
然后按照规律模拟即可
我们没必要求解要那么多想 斐波那契92项时就已经炸掉了long long
我们只要考虑前90几项即可
#include<bits/stdc++.h>
using namespace std;
long long f[100];
int main()
{
string s[10];
cin>>s[1]>>s[2];
f[1]=s[1].length();
f[2]=s[2].length();
s[3]=s[2]+s[1];
int k=0;
for(int i=3; i<=100; i++)
{
f[i]=f[i-1]+f[i-2];
if(f[i]>1e18)
{
k=i;
break;
}
}
int q;
cin>>q;
while(q--)
{
long long x,y;
cin>>x>>y;
if(x==1)
{
cout<<s[x][y-1]<<endl;
continue;
}
x=lower_bound(f+2,f+1+k,y)-f;
while(x>3)
{
if(y>f[x-1])
{
y-=f[x-1];
x-=2;
}
else x--;
}
cout<<s[x][y-1]<<endl;
}
}