牛客练习赛75

牛客练习赛75

幸好最后选择了飞机, 火车不然就被隔离了

在家效率是真的低, 脑子还不想动

A 广义肥波

线性推一下, 就行, 无非取膜的mod把人卡住, 对于指数要取膜mod-1的

p ∈ prime, a % p != 0, a^(p - 1) ≡ 1 (mod p),

故 a^(x) = a^(x - (p - 1)) = a^x / 1 (mod p)

所以对于指数取膜 mod - 1

ll f[N] = { 1, 1, 1 };
ll qpow(ll a, ll b) { ll ans = 1; for (; b; b >>= 1, a = a * a % mod) if (b & 1) ans = ans * a % mod; return ans; }
int main() {
    IOS; ll a, b; cin >> a >> b >> m >> n;
    rep (i, 3, n) f[i] = (a * f[i - 1] + b * f[i - 2]) % (mod - 1);
    return cout << qpow(m, f[n]), 0;
}

B 小D和他的魔法石

贪心, 直接交换之后选择性价比最高的石头完事

注意到当 k == 0 or n == 2 时 无法贪心(无法交换 or 交换结果唯一), 需要莽, 也就是成了完全背包

int main() {
    IOS; cin >> n >> m >> k; ll ans = 0;
    rep (i, 1, n) cin >> a[i];
    rep (i, 1, n) cin >> b[i];
    if (n == 2 || k == 0) {
        if (n == 2 && k % 2) swap(b[1], b[2]);
        rep (i, 1, n) rep (j, a[i], m) umax(f[j], f[j - a[i]] + b[i]), umax(ans, f[j]);
    } else {
        sort(a + 1, a + 1 + n); sort(b + 1, b + 1 + n, greater<int>());
        ans = m / a[1] * b[1];
    }
    cout << ans;
    return 0;
}

D 减数游戏

这题不难想, 主要是数据太大的问题

用python, java 大数可以莽过

其实可以注意到, 再迭代到, 堆中最小两个数 a, b, a * b + k >= 堆中最大值的时候

已经有序了, a * b + k 放进堆中一定时堆中最大值, 然后再取两个最小的数, 其合并放入堆中也必定时最大值 >= a * b + k

int main() {
    IOS; cin >> n >> k;
    priority_queue<pair<int, ll>, vector<pair<int, ll>>, greater<pair<int, ll>>> q;
    rep (i, 1, n) cin >> _, q.push({ 0, _ }), umax(m, _); _ = 0;
    rep (i, 2, n) {
        auto x = q.top(); q.pop();
        auto y = q.top(); q.pop();
        x.se = x.se * y.se + k;
        if (x.se >= m || _) x.fi = ++_;
        q.push({ x.fi, x.se % mod });
    }
    return cout << q.top().se, 0;
}

C 宝石街

先贪心的想想, 最好的情况就是正好到个整数点直接白嫖当前的所有石头

所以我们可以枚举路径的结束点, 再找起始点, 尺取刚刚好

int main() {
    IOS; cin >> n >> t >> k;
    if (k == 1) rep (i, 1, n) cin >> a[i];
    else {
        cin >> a[1] >> p;
        rep (i, 2, n) {
            ull c = a[i - 1], x = c ^ (c << 13), y = x ^ (x >> 17);
            a[i] = (y ^ (y << 5)) % p + 1;
        }
    }
    for (int i = n, cur = n; i; --i, umax(ans, res + (cur ? (t - s) / (i - cur) : 0))) {
        res -= a[i + 1], s -= res;
        while (cur && (i == cur || (t - s) / (i - cur) >= a[cur])) s += (i - cur) * a[cur], res += a[cur--];
    }
    cout << ans;
    return cout << ans, 0;
}

E 炒鸡矿工

dp, 二维的线性dp

int main() {
    memset(f, -1, sizeof f);
    IOS; cin >> s[0] >> v[0] >> n >> f[0][0] >> t;
    rep(i, 1, n) cin >> w[i];
    rep(i, 1, n) cin >> v[i], v[i] += v[i - 1];
    rep(i, 1, n) cin >> s[i];
    rep(i, 0, t - 1) {
        rep(j, 0, n - 1) if (f[i][j] >= w[j + 1]) umax(f[i][j + 1], f[i][j] - w[j + 1]);
        rep(j, 0, n) if (i + s[j] <= t && f[i][j] > -1) umax(f[i + s[j]][j], f[i][j] + v[j]), umax(ans, f[i + s[j]][j]);
    }
    cout << ans;
    return 0;
}
原文地址:https://www.cnblogs.com/2aptx4869/p/14233308.html