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);
}
View Code

 

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);
}
View Code

 

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);
}
View Code

 

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);
}
View Code

 

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);
}
View Code

 

posted @ 2020-09-25 11:06  若讷  阅读(322)  评论(0编辑  收藏  举报