CF226C Anniversary
首先有个显然的性质:\(\gcd(F_a,F_b)-F_{\gcd(a, b)}\),其中 \(F\) 指斐波那契数列。
那么问题就转化成在区间 \([l,r]\) 中找 \(k\) 个不同的数字使得这些数字的最大公约数最大。
那么在一个区间 \([l,r]\) 中,有因子 \(x\) 的数的数量是 \(r/x-(l-1)/x\) 个,我们在 \(\sqrt{r}\) 中寻找 \(i\) 和 \(r/i\) 的有因子 \(x\) 的数的数量是否大于等于 \(k\),记录下最大的一个因子 \(id\),那么最后的答案就是 \(F_{id}\)。
注意要随时取模,模数是数据给出的。
#include <bits/stdc++.h>
#define reg register
#define ll long long
#define int long long
#define ull unsigned long long
#define db double
#define pi pair<int, int>
#define pl pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define vpi vector<pi>
#define vpl vector<pl>
#define pb push_back
#define er erase
#define SZ(x) (int) x.size()
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define mkp make_pair
#define dmin(x, y) ((x) < (y) ? (x) : (y))
#define dmax(x, y) ((x) > (y) ? (x) : (y))
#define checkmax(x, y) ((x) < (y) ? ((x) = (y)) : (x))
#define checkmin(x, y) ((x) > (y) ? ((x) = (y)) : (x))
#define ms(data_name) memset(data_name, 0, sizeof(data_name))
#define msn(data_name, num) memset(data_name, num, sizeof(data_name))
#define pls(x, y) ((x) + (y) >= m ? (x) + (y) - m : (x) + (y))
#define mul(x, y) (1ll * (x) * (y) % m)
#define For(i, j) for(reg int (i) = 1; (i) <= (j); ++(i))
#define For0(i, j) for(reg int (i) = 0; (i) < (j); ++(i))
#define Forx(i, j, k) for(reg int (i) = (j); (i) <= (k); ++(i))
#define Forstep(i , j, k, st) for(reg int (i) = (j); (i) <= (k); (i) += (st))
#define fOR(i, j) for(reg int (i) = (j); (i) >= 1; (i)--)
#define fOR0(i, j) for(reg int (i) = (j) - 1; (i) >= 0; (i)--)
#define fORx(i, j, k) for(reg int (i) = (k); (i) >= (j); (i)--)
#define tour(i, u) for(reg int (i) = head[(u)]; (i) != -1; (i) = nxt[(i)])
using namespace std;
char ch, B[1 << 20], *S = B, *T = B;
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 20, stdin), S == T) ? 0 : *S++)
#define isd(c) (c >= '0' && c <= '9')
int rdint() {
int aa, bb;
while(ch = getc(), !isd(ch) && ch != '-');
ch == '-' ? aa = bb = 0 : (aa = ch - '0', bb = 1);
while(ch = getc(), isd(ch))
aa = aa * 10 + ch - '0';
return bb ? aa : -aa;
}
ll rdll() {
ll aa, bb;
while(ch = getc(), !isd(ch) && ch != '-');
ch == '-' ? aa = bb = 0 : (aa = ch - '0', bb = 1);
while(ch = getc(), isd(ch))
aa = aa * 10 + ch - '0';
return bb ? aa : -aa;
}
ll mod, l, r, k;
struct Matrix {
ll a[3][3];
Matrix() { memset(a, 0, sizeof a); }
Matrix operator*(const Matrix &b) const {
Matrix res;
for (int i = 1; i <= 2; ++i)
for (int j = 1; j <= 2; ++j)
for (int k = 1; k <= 2; ++k)
res.a[i][j] = (res.a[i][j] + 1ll * a[i][k] * b.a[k][j] % mod) % mod;
return res;
}
} ans, base;
void init() {
base.a[1][1] = base.a[1][2] = base.a[2][1] = 1;
ans.a[1][1] = ans.a[1][2] = 1;
}
void qpow(int b) {
while (b) {
if (b & 1) ans = ans * base;
base = base * base;
b >>= 1;
}
}
inline void work() {
mod = rdll();
l = rdll();
r = rdll();
k = rdll();
int id = 0;
for(reg ll i = 1; i * i <= r; ++i) {
if(r / i - (l - 1) / i >= k) {
checkmax(id, i);
}
if(r / (r / i) - (l - 1) / (r / i) >= k) {
checkmax(id, r / i);
}
}
// cout << id << endl;
if(id <= 2) {
id = 1 % mod;
printf("%lld\n", id);
} else {
init();
qpow(id - 2);
printf("%lld\n", ans.a[1][1] % mod);
}
}
signed main() {
// freopen("input.txt", "r", stdin);
work();
return 0;
}