QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#95732#5602. Sun and Moon__#WA 2ms3452kbC++143.9kb2023-04-11 18:39:162023-04-11 18:39:20

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-04-11 18:39:20]
  • 评测
  • 测评结果:WA
  • 用时:2ms
  • 内存:3452kb
  • [2023-04-11 18:39:16]
  • 提交

answer

#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")

#include <bits/stdc++.h>
using namespace std;

#define el '\n'
#define F first
#define S second

typedef long long ll;
typedef long double ld;

bool multipleTestCases = 0, sublime = 0;
const int N = 4e5 + 5, INF = 1e9 + 5, mod = 1e9 + 7, LOG = 22, SQ = 500;

void move1step(ll &a, ll &b, ll q){
    ll next = a - q * b;
    a = b;
    b = next;
}

ll eGCD(ll r0, ll r1, ll &x0, ll &y0){
    if(r0 < 0){
        ll ret = eGCD(-r0, r1, x0, y0);
        x0 *= -1;
        return ret;
    }

    if(r1 < 0){
        ll ret = eGCD(r0, -r1, x0, y0);
        y0 *= -1;
        return ret;
    }

    ll q, x1, y1;
    x0 = y1 = 1;
    x1 = y0 = 0;

    while(r1){
        q = r0 / r1;
        move1step(r0, r1, q);
        move1step(x0, x1, q);
        move1step(y0, y1, q);
    }

    return r0;
}

/*
aX + bY = g
aXt + bYt = c = gt

t = c / g
x *= t, y *= t
xUnit = b / g, yUnit = a / g;
*/

// if you want to use with Y pass: (y, x, yUnit, xUnit, bar, orEqual)

void raiseXOverBar(ll &x, ll &y, ll &xUnit, ll &yUnit, ll bar, bool orEqual){
    if(x > bar or (x == bar and orEqual))
        return;

    ll shift = (bar - x + xUnit - orEqual) / xUnit;
    x += shift * xUnit;
    y -= shift * yUnit;
}

void lowerXUnderBar(ll &x, ll &y, ll &xUnit, ll &yUnit, ll bar, bool orEqual){
    if(x < bar or (x == bar and orEqual))
        return;

    ll shift = (x - bar + xUnit - orEqual) / xUnit;
    x -= shift * xUnit;
    y += shift * yUnit;
}

void minXOverBar(ll &x, ll &y, ll &xUnit, ll &yUnit, ll bar, bool orEqual){
    if(x < bar or (x == bar and !orEqual)){
        ll shift = (bar - x + xUnit - orEqual) / xUnit;
        x += shift * xUnit;
        y -= shift * yUnit;
    }
    else{
        ll shift = (x - bar - !orEqual) / xUnit;
        x -= shift * xUnit;
        y += shift * yUnit;
    }
}

void maxXUnderBar(ll &x, ll &y, ll &xUnit, ll &yUnit, ll bar, bool orEqual){
    if(x < bar or (x == bar and orEqual)){
        ll shift = (bar - x - !orEqual) / xUnit;
        x += shift * xUnit;
        y -= shift * yUnit;
    }
    else{
        ll shift = (x - bar + xUnit - orEqual) / xUnit;
        x -= shift * xUnit;
        y += shift * yUnit;
    }
}

/// calculate each two congruences then solve with next: sol(sol(sol(1, 2), 3), 4)

/// T = x mod N                  -> T = N * k + x
/// T = y mod M                  -> T = M * p + y
/// N * k + x = M * p + y        -> N * k - M * p = y - x (LDE)
ll CRT(vector<ll> &rems, vector<ll> &mods){
    ll prevRem = rems[0], prevMod = mods[0]; /// first congruence

    for(int i = 1; i < rems.size(); i++){
        ll x, y, c = rems[i] - prevRem;

        if(c % __gcd(prevMod, -mods[i])) /// LDE can't be solved (no answer to system of congruences)
            return -1;

        ll g = eGCD(prevMod, -mods[i], x, y);
        x *= c / g;

        prevRem += prevMod * x;
        prevMod = prevMod / g * mods[i];
        prevRem = ((prevRem % prevMod) + prevMod) % prevMod;
    }

    return prevRem;
}

void doWork() {
    ll pastSun, nextSun, pastMoon, nextMoon, totSun, totMoon, mx = 0;

    cin >> pastSun >> nextSun >> pastMoon >> nextMoon;

    mx = max(mx, pastSun);
    mx = max(mx, pastMoon);

    totSun = nextSun;
    totMoon = nextMoon;

    ll g = __gcd(totSun, totMoon);
    ll lcm = (totSun / g) * totMoon;

    vector<ll> rems = {pastSun, pastMoon}, mods = {totSun, totMoon};

    ll mn = CRT(rems, mods);

    cout << (mn + lcm) - (mn + mx);
}

signed main() {
#ifdef ONLINE_JUDGE
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#endif
#ifndef ONLINE_JUDGE
    if (sublime) {
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    }
#endif
    int tests = 1;
    if (multipleTestCases) {
        cin >> tests;
    }
    for (int tc = 1; tc <= tests; tc++) {
        doWork();
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 3404kb

input:

3 10
1 2

output:

7

result:

ok single line: '7'

Test #2:

score: -100
Wrong Answer
time: 2ms
memory: 3452kb

input:

27 32
39 41

output:

1273

result:

wrong answer 1st lines differ - expected: '453', found: '1273'