Skip to main content
  1. Posts/

CodeForces-1361B Johnny and Grandmaster

·2 mins·

CodeForces-1361B Johnny and Grandmaster #

题目大意 #

给定 $p$ 和长度为 $n$ 的数组 $k$ . 把数组 $k$ 划分成两部分 $A,B$, 求 $\vert \sum_{v\in A}p^{v} - \sum_{v\in B}p^{v}\vert$ 的最小值.

Solution 1 #

由于幂次的特性, 不难想到贪心. 取最大元素的放入一个子数组中, 然后取稍小的元素尽可能将其抵消. 比较 tricky 的部分是用栈 + 拆分实现这个过程. 代码如下:

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

#define ll long long

const ll MOD = 1e9 + 7;

ll mypow(ll p, ll k) {
    ll res = 1;
    while (k) {
        if (k & 1) {
            res = (res * p) % MOD;
            k--;
        }
        k /= 2;
        p = p * p % MOD;
    }
    return res;
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        ll ans = 0;
        ll n, p;
        cin >> n >> p;
        vector<ll> a(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        if (p == 1) {
            cout << (n & 1) << endl;
            continue;
        }
        sort(a.begin(), a.end(), greater<ll>());
        stack<int> s;
        s = stack<int>();
        int i = 0;
        for (i = 0; i < n; i++) {
            if (s.empty()) {
                s.push(a[i]);
            } else {
                if (a[i] < s.top()) { 
                    bool isEnd = false;
                    ll cnt = 1;
                    for (int j = 0; j < s.top() - a[i] && !isEnd; j++) {
                        cnt *= p;
                        if (cnt >= n - i) {
                            isEnd = true; 
                            break;
                        }
                    }
                    if (isEnd) {
                        break;
                    } 
                    else {
                        s.pop();
                        while (cnt--) {
                            s.push(a[i]);
                        }
                    }
                }
                if (a[i] == s.top()) {
                    s.pop();
                }
            }
        }
        while (!s.empty()) {
            ans = (ans + mypow(p, s.top())) % MOD;
            s.pop();
        }
        for (int k = i; k < n; k++) {
            ans = (ans - mypow(p, a[k]) + MOD) % MOD;
        }
        cout << ans << endl;
    }
    return 0;
}