求区别,悬棺~
查看原帖
求区别,悬棺~
358971
朦胧_XY楼主2023/9/29 22:03

AC:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int INF = 1<<30;
int n, k;
int exgcd(int a, int b, int &x, int &y){
    if(!b){ x = 1, y = 0; return a; }
    int g = exgcd(b, a % b, x, y), t = x;
    x = y, y = t - a/b * y;
    return g;
}
void solve(){
    scanf("%d%d", &n, &k);
    int a = n / k, p = k - n % k;
    int b = n / k + 1, q = n % k;
    int x, y, g = exgcd(a, b, x, y);
    if(n / 2 % g){ printf("No\n"); return; }
    x = x / g * (n / 2), y = y / g * (n / 2);
    int l = -INF, r = INF, l1 = r, r1 = l, l2 = r, r2 = l;
    while(l <= r){
        int mid = l + r >> 1;
        if(x + mid * (b / g) >= 0) r = mid - 1, l1 = mid;
        else l = mid + 1;
    }
    l = -INF, r = INF;
    while(l <= r){
        int mid = l + r >> 1;
        if(x + mid * (b / g) <= p) l = mid + 1, r1 = mid;
        else r = mid - 1;
    }
    l = -INF, r = INF;
    while(l <= r){
        int mid = l + r >> 1;
        if(y - mid * (a / g) <= q) r = mid - 1, l2 = mid;
        else l = mid + 1;
    }
    l = -INF, r = INF;
    while(l <= r){
        int mid = l + r >> 1;
        if(y - mid * (a / g) >= 0) l = mid + 1, r2 = mid;
        else r = mid - 1;
    }
    printf("%s\n", max(l1, l2) <= min(r1, r2) ? "Yes" : "No");
}
signed main(){
    int T;
    cin >> T;
    while(T--) solve();
    return 0;
}

WA:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int INF = 1<<30;
int n, k;
int exgcd(int a, int b, int &x, int &y){
    if(!b){ x = 1, y = 0; return a; }
    int g = exgcd(b, a % b, x, y), t = x;
    x = y, y = t - a/b * y;
    return g;
}
void solve(){
    scanf("%lld%lld", &n, &k);
    int a = n / k, p = k - n % k;
    int b = n / k + 1, q = n % k;
    int x, y, g = exgcd(a, b, x, y);
    if(n/2 % g){ printf("No\n"); return; }
    x = x / g * (n/2), y = y / g * (n/2);
    int l = -INF, r = INF, lm = r, rm = l;
    while(l <= r){
        int mid = l+r >> 1;
        if(x + mid * (b/g) >= 0) r = mid - 1, lm = mid;
        else l = mid + 1;
    }
    l = -INF, r = INF;
    while(l <= r){
        int mid = l+r >> 1;
        if(x + mid * (b/g) <= p) l = mid + 1, rm = mid;
        else r = mid - 1;
    }
    printf("%s\n", lm<=rm&&y-lm*(a/g)<=q&&y-rm*(a/g)>=0 ? "Yes" : "No");
}
signed main(){
    int T;
    cin >> T;
    while(T--) solve();
    return 0;
}

AC 的是算出使 x 成立的 m 取值范围和使 y 成立的 m 取值范围,看两个取值范围若有交集则 m 有解;
WA 的是算出使 x 成立的 m 取值范围,然后将该 m 取值范围带入 y,看 y 是否有成立的,若成立则有解。

2023/9/29 22:03
加载中...