小麦亩产一千八
jzoj 3461
题目大意
给你一个正整数序列:a0,a1,a2a_0,a_1,a_2a0,a1,a2……
a0a_0a0为1
a1a_1a1为p
ax=ax−1+ax−2(x>1)a_x=a_{x-1} + a_{x-2}(x>1)ax=ax−1+ax−2(x>1)
现在给你三个数x,ax,yx,a_x,yx,ax,y,让你判断该序列是否合法,然后求aya_yay是的值(多组数据)
输入样例
1 1 2
3 5 4
3 4 6
12 17801 19
输出样例
2
8
-1
516847
样例解释
对于样例二,f[1]=2 时,能够满足f[3]=5,因此宰相没有撒谎,此时第5 个格子的小麦数应为f[4]=f[2]+f[3]=3+5=8.
数据范围
对于50%的数据:如果答案存在,那么p⩽50p\leqslant 50p⩽50
对于100%的数据:1⩽1\leqslant1⩽ 数据组数⩽10000\leqslant 10000⩽10000,1⩽a,b⩽201\leqslant a,b\leqslant 201⩽a,b⩽20, 数据保证如果答案存在,那么⩽p⩽1000000.\leqslant p\leqslant 1000000.⩽p⩽1000000.
解题思路
因为a,b很小,我们可以提前求出前二十个数的常熟项和一次项系数,我们减去常数项,如果能整除一次项系数那它就是p,然后直接求aya_yay即可
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll x, y, p, xs, a[30], b[30];
int main()
{a[0] = 1;b[1] = 1;for (int i = 2; i <= 20; ++i)a[i] = a[i - 1] + a[i - 2], b[i] = b[i - 1] + b[i - 2];//预处理while(~scanf("%lld%lld%lld", &x, &xs, &y)){if ((xs - a[x]) % b[x] == 0) p = (xs - a[x]) / b[x];//判断是否合法else p = 0;if (p) printf("%lld\n", a[y] + b[y] * p);//求结果else printf("-1\n");}return 0;
}