Codeforces 710D Two Arithmetic Progressions 题解 [ 绿 ] [ 值域分治 ] [ 剩余系 ] [ exgcd ]

Two Arithmetic Progressions

0a2fbbc7ac98223c64cd9dfcf94c3e6f

简单根号分治题。

负数显然不好搞,我们先从 \(b,d\) 其中一个作为原点,这样更容易处理。

然后考虑做法,发现这个东西是一个不断跳跃的形式,很像根号分治的板题,于是对步长(公差)考虑根号分治

  • \(\min(a,c) \ge B\)
    • 此时最多只会跳 \(10^6\) 左右步,就一定能跳到边界,暴力跳即可。时间复杂度 \(O(\dfrac{V}{B})\)
  • \(\min(a,c) \le B\)
    • 因为 \(a,c\) 很小,所以从循环节的角度考虑,先钦定 \(a,c\) 当中小的那一个作为模数,然后就是求一个模 \(\min(a,c)\)剩余系。为了方便,我们考虑将 \(a,c\)更小的那一个数列作为有原点的那个数列,那么更大的那一个数跳的路线就是先跳若干步进入循环节,然后在循环节中以固定的步数不断跳跃。因为模数很小,所以循环节的长度也很小,直接暴力求循环节和起始点即可。如果跳了 \(\min(a,c)\) 次都找不到就说明无解。时间复杂度 \(O(B)\)

平衡一下发现 \(B = \sqrt{V}\) 的时候复杂度最优,于是总体时间复杂度就是 \(O(\sqrt{V})\) 的。

#include <bits/stdc++.h>
#define fi first
#define se second
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
#define lc(x) (tr[x].ls)
#define rc(x) (tr[x].rs)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi = pair<int, int>;
ll a, b, c, d;
ll solve(ll lmt)
{
    ll now = d, ans = 0;
    if(a >= sqrt(lmt))
    {
        while(now <= lmt)
        {
            ans += (now % a == 0);
            now += c;
        }
        return ans;
    }
    bool flag = 0;
    for(int i = 1; i <= a && now <= lmt; i++)
    {
        if(now % a == 0)
        {
            ans++;
            flag = 1;
            break;
        }
        now += c;
    }
    if(flag == 0) return ans;
    ll st = now;
    flag = 0;
    for(int i = 1; i <= a && now <= lmt; i++)
    {
        now += c;
        if(now % a == 0)
        {
            flag = 1;
            break;
        }
    }
    if(flag == 0) return ans;
    ll gap = now - st;
    return (ans + (lmt - st) / gap);
}
int main()
{
    //freopen("sample.in", "r", stdin);
    //freopen("sample.out", "w", stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll l, r;
    cin >> a >> b >> c >> d >> l >> r;
    if(a > c) swap(b, d), swap(a, c);
    d -= b; l -= b; r -= b; b = 0;
    if(d < 0) d += ceil(1.0 * (-d) / c) * c;
    cout << solve(r) - solve(l - 1);
    return 0;
}
posted @ 2025-08-13 22:28  KS_Fszha  阅读(7)  评论(0)    收藏  举报