Codeforces Round #672 (Div. 2)
A. Cubes Sorting
题意: 询问逆序对个数是否不大于$ \frac{n * (n - 1)}{2} - 1 $
最不理想的情况就是单调下降序列,此时的逆序对个数为$ \frac{n * (n - 1)}{2} $,只要不为单调下降序列就满足题意
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b) for (register int i = a; i <= b; i++) int n, a[50010]; int b[50010]; inline void solve(int T) { cin >> n; rep(i, 1, n) cin >> a[i]; rep(i, 2, n) { if(a[i] >= a[i - 1]) { cout << "YES\n"; return; } } cout << "NO\n"; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); // freopen("in.txt", "r", stdin); // freopen("out2.txt", "w", stdout); int T = 1; cin >> T; rep(i, 1, T) solve(i); }
B. Rock and Lever
题意: 已知序列 ${a_i}$, 求$a_i \& a_j \geq a_i \oplus a_j, i < j$的个数
容易发现,当两个数转化成二进制位数相同的时候满足条件,简单的计算一下就可
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b) for (register int i = a; i <= b; i++) ll n; ll a[100010]; ll cnt[50]; ll ans; inline void solve(int T) { cin >> n; memset(cnt, 0, sizeof(cnt)); rep(i, 1, n) { cin >> a[i]; int tmp = 0; while(a[i]) { tmp++; a[i] /= 2; } cnt[tmp]++; } ans = 0; rep(i, 1, 49) ans += cnt[i] * (cnt[i] - 1) / 2; cout << ans << endl; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); // freopen("in.txt", "r", stdin); // freopen("out2.txt", "w", stdout); int T = 1; cin >> T; rep(i, 1, T) solve(i); }
C1. Pokémon Army (easy version)
题意: 从序列中选择若干个数,最大化$a_{b_1}-a_{b_2}+a_{b_3}-a_{b_4}...$
考虑dp,$dp[i[[0]$表示加上第$i$个数的最大值,$dp[i][1]$ 表示减去第$i$个数的最大值
所以$dp[i][0]=max(dp[j][1]) + a[i], dp[i][1]=max(dp[j][0])-a[i],j<i$
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b) for (register int i = a; i <= b; i++) ll n, q; ll a[300010]; ll dp[300010][2], mx[2], ans; inline void solve(int T) { cin >> n >> q; rep(i, 1, n) cin >> a[i]; mx[0] = mx[1] = ans = 0; rep(i, 1, n) { dp[i][0] = mx[1] + a[i]; dp[i][1] = mx[0] - a[i]; mx[0] = max(mx[0], dp[i][0]); mx[1] = max(mx[1], dp[i][1]); ans = max(ans, mx[0]); } cout << ans << endl; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); // freopen("in.txt", "r", stdin); // freopen("out2.txt", "w", stdout); int T = 1; cin >> T; rep(i, 1, T) solve(i); }
C2. Pokémon Army (hard version)
有个贪心的结论,答案为序列差分数组正数的和。
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b) for (register int i = a; i <= b; i++) ll n, q; ll a[300010]; ll ans; inline void solve(int T) { cin >> n >> q; ans = a[n + 1] = 0; rep(i, 1, n) { cin >> a[i]; if(a[i] - a[i - 1] > 0) ans += a[i] - a[i - 1]; } cout << ans << endl; ll l, r; rep(i, 1, q) { cin >> l >> r; ll tmp1 = a[l], tmp2 = a[r]; ans -= max(a[l + 1] - tmp1, 0ll) + max(tmp1 - a[l - 1], 0ll); a[l] = tmp2; ans += max(a[l + 1] - tmp2, 0ll) + max(tmp2 - a[l - 1], 0ll); ans -= max(a[r + 1] - tmp2, 0ll) + max(tmp2 - a[r - 1], 0ll); a[r] = tmp1; ans += max(a[r + 1] - tmp1, 0ll) + max(tmp1 - a[r - 1], 0ll); cout << ans << endl; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); int T = 1; cin >> T; rep(i, 1, T) solve(i); }
D. Rescue Nibel!
题意: 选择$k$个等使得这$k$个灯至少在某一时刻同时亮着
枚举时刻,在当前时刻才亮的灯与前一个时刻亮到当前时刻的灯进行组合
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b) for (register int i = a; i <= b; i++) struct bulb { int l, r; bool operator<(bulb & f) const { if(l == f.l) return r < f.r; return l < f.l; } }a[300010]; ll n, k, cnt, ans; priority_queue<int, vector<int>, greater<int> > q; ll mod = 998244353; ll ksm(ll x, ll b) { ll res = 1; for (; b; b >>= 1, x = x * x % mod) if (b & 1) res = res * x % mod; return res; } ll fac[300010], inv[300010]; ll C(ll f, ll j) { return fac[f] * inv[j] % mod * inv[f - j] % mod; } inline void solve(int T) { cin >> n >> k; rep(i, 1, n) cin >> a[i].l >> a[i].r; sort(a + 1, a + n + 1); for(int i = 1; i <= n; ) { int flag = a[i].l, tmp = 0; while(flag == a[i].l) { q.push(a[i].r); tmp++; i++; } while(q.top() < flag) { q.pop(); cnt--; } rep(j, max(1ll, k - cnt), k) if(tmp >= j) { ans += C(cnt, k - j) * C(tmp, j) % mod; ans %= mod; } else break; cnt += tmp; } cout << ans << endl; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); fac[0] = inv[0] = 1; rep(i, 1, 300000) fac[i] = fac[i - 1] * i % mod; inv[300000] = ksm(fac[300000], mod - 2); for (int i = 299999; i > 0; i--) inv[i] = inv[i + 1] * (i + 1) % mod; // freopen("in.txt", "r", stdin); // freopen("out2.txt", "w", stdout); int T = 1; // cin >> T; rep(i, 1, T) solve(i); }