牛客练习赛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;
}