Codeforces Round 969 (Div. 2) C. Dora and C++ (裴蜀定理)

在这里插入图片描述
什么?竟然是裴蜀定理。。。


由于这里给出了a和b两个数,我们或许可以想到使用同样是需要给出两个定值的裴蜀定理,即:

  • 如果给定 x x x y y y,那么一定有 a x + b y = g c d ( x , y ) ax+by=gcd(x,y) ax+by=gcd(x,y)

所以在这时候我们就可以让输入的所有数都去对 g c d ( a , b ) gcd(a,b) gcd(a,b)取模,这样就能够得到所有数的最简形式(可以当成是让所有数尽可能消去 a a a b b b的组成)。

至于这里为什么能减:

  • 虽然这里给我们的条件是只能够加,但是一个数加了就相当于其他数都在减,所以我们可以直接将其转化为减操作。

那么在取模之后我们现在排序,得到的极差就是 c [ n ] − c [ 1 ] c[n] - c[1] c[n]c[1],那么这里我们还要进行一次 o ( n ) o(n) o(n)的判断,因为不排除有这种情况存在 c [ i ] + g − c [ i − 1 ] < c [ n ] − c [ 1 ] c[i] + g - c[i-1] < c[n] - c[1] c[i]+gc[i1]<c[n]c[1],这样我们会取到最优解。

void solve()
{
    int n,a,b;cin >> n >> a >> b;
    int g = __gcd(a,b);
    vector<int>c(n);
    for(int i = 0;i < n;i++){
        cin >> c[i];
        c[i]%=g;
    }

    sort(c.begin(),c.end());

    int res = c[n-1] - c[0];

    for(int i = 1;i < n;i++){
        res = min(res,c[i] + g - c[i-1]);
    }

    cout << res << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值