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;
}
posted @ 2020-09-12 22:43  Nylch  阅读(76)  评论(0编辑  收藏  举报