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

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;
}