巴西区域赛补题C. Creating Multiples —— 数学*

该篇博客探讨了一种编程问题的解决方案,利用数学性质x^n%(x+1)的值仅为1和x,来解决在B进制下使新数模(B+1)余零的问题。通过遍历数的二进制位并进行适当修改,找到最小的修改方案。文章适合对算法和数学感兴趣的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Link

题意:

给出B进制下每一位大小,从中选一位将其改小,使得新数M模(B+1)余零。输出改哪一位以及改成几,如果有多种改法,选择使得M最小的一种。

思路:

注意到对任意一个数,x ^ n % (x + 1)的值只为1和x,其中当n为奇数时为x,否则为1,利用这个性质可以简单的写出代码,注意遍历时从高位向低位即可。

// Decline is inevitable,
// Romance will last forever.
#include <bits/stdc++.h>
using namespace std;
#define mst(a, x) memset(a, x, sizeof(a))
#define INF 0x3f3f3f3f
//#define mp make_pair
//#define pii pair<int,int>
#define fi first
#define se second
#define ll long long
//#define int long long
#define pb push_back
const int maxn = 1e4 + 10;
const int maxm = 3e5 + 10;
const int P = 1e9 + 7;
int n, k;
int a[maxn];
void solve() {
    int b, l;
    cin >> b >> l;
    int yu = 0;
    for(int i = l; i >= 1; i--) {
        cin >> a[i];
        if(i & 1)
            yu = (yu + a[i]) % (b + 1);
        else
            yu = (yu + a[i] * b) % (b + 1);
    }
    if(!yu) {
        cout << 0 << ' ' << 0 << endl;
        return;
    }
    for(int i = l; i >= 1; i--) {
        if(i & 1) {
            if(a[i] < yu) continue;
            cout << l-i+1 << ' ' << a[i]-yu << endl;
            return;
        }
        else {
            if(a[i] < b + 1 - yu) {
                continue;
            }
            cout << l-i+1 << ' ' << a[i]-b-1+yu << endl;
            return;
        }
    }
    cout << -1 << ' ' << -1 << endl;
}
signed main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//    int T; scanf("%d", &T); while(T--)
//    int T; cin >> T; while(T--)
    solve();
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值