Codeforces Global Round 19 A - E

Posted by webpals on Sun, 13 Feb 2022 10:33:58 +0100

https://codeforces.com/contest/1637

A

Select a length len, sort the number of the first len and the number of the next len respectively, and ask whether the array can always be arranged well

  • Obviously, only the array has been ordered before
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> a(n);
        for(auto &i : a) cin >> i;
        if(!is_sorted(a.begin(), a.end())) cout << "YES\n";
        else cout << "NO\n";
    }
    return 0;
}

B

  • According to the given rules, ask the maximum value of all subarrays of this array after division
  • I've been thinking about this problem for a long time, but I can't figure out what the optimal solution is. In fact, it's always optimal to divide an array with length k into k segments. When there is no 0, it's K. use other division methods, such as randomly dividing one. Suppose that two interval lengths are divided into l , r l, r l. R, here l + r = k l+r=k l+r=k, then the answer is 2 + 0 + 0 = 2 ≤ k 2+0+0=2\leq k 2 + 0 + 0 = 2 ≤ k can be divided at most k k k; Even if there is 0, the contribution to the answer is greater because m e x ( 0 ) = 1 mex(0)=1 mex(0)=1, while the maximum is only 0 when 0 is divided into other groups k k k
  • This question is very clever, so it's called interval [ l , r ] [l,r] The contribution of [l,r] to the answer is r − l + 1 + r e s r-l+1+res r − l+1+res, where r e s res res represents the number of intervals 0. The time complexity of enumerating each interval is O ( n 2 ) O(n^2) O(n2)
#include <bits/stdc++.h>

using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> a(n);
        for(int i=0;i<n;i++) cin >> a[i];
        long long ans = 0;
        function<long long(int, int)> cal = [&](int l, int r){
            long long res = 0;
            for(int i=l;i<=r;i++){
                if(!a[i]){
                    res += 1;
                }
            }
            return res + r - l + 1;
        };
        for(int i=0;i<n;i++){
            for(int j=i;j<n;j++){
                ans += cal(i, j);
            }
        }
        cout << ans << '\n';
    }
    return 0;
}

C

  • I read the question wrong and thought about it for a long time. It's said here 1 < j < n 1\lt j\lt n 1 < J < n, that's simple. If it's an odd number, then + 1, and then / 2. If it's an even number, direct / 2. If the middle is all 1 or the length is 3, if the middle is an odd number, there's no solution; Otherwise, there is always a solution, because for example, it is 1
    3 1, this 3 can produce two even numbers, and even numbers can make odd numbers become even numbers
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> a(n);
        for(auto &i : a) cin >> i;
        function<void()> solve = [&](){
            if(n == 3 && (a[1] & 1)){
                cout << -1 << '\n';
                return; 
            }
            ll ans = 0;
            bool ok = false;
            for(int i=1;i<n-1;i++){
                if(a[i] != 1) ok = true;
            }
            if(!ok){
                cout << -1 << '\n';
            }else{
                for(int i=1;i<n-1;i++){
                    if(a[i] & 1){
                        a[i] += 1;
                    }
                    ans += a[i] / 2;
                }
                cout << ans << '\n';
            }
        };
        solve();
    }
    return 0;
}

D

  • Such a question, here you are a [ i ] a[i] a[i] and b [ i ] b[i] b[i], now minimize ∑ i = 1 n ∑ j = i + 1 n ( a i + a j ) 2 \sum_{i=1}^{n}\sum_{j=i+1}^{n}(a_i+a_j)^2 Σ i=1n Σ j=i+1n (ai + aj) 2 and ∑ i = 1 n ∑ j = i + 1 n ( b i + b j ) 2 \sum_{i=1}^{n}\sum_{j=i+1}^{n}(b_i+b_j)^2 Σ i=1n Σ j=i+1n (bi + bj) 2
  • Square open, then add and get ∑ i = 1 n ∑ j = i + 1 n a i 2 + b i 2 + a j 2 + b j 2 + 2 ( a i a j + b i b j ) \sum_{i=1}^{n}\sum_{j=i+1}^{n}a_i^2+b_i^2+a_j^2+b_j^2+2(a_ia_j+b_ib_j) ∑i=1n​∑j=i+1n​ai2​+bi2​+aj2​+bj2​+2(ai​aj​+bi​bj​)
  • front ∑ i = 1 n ∑ j = i + 1 n a i 2 + b i 2 + a j 2 + b j 2 \sum_{i=1}^{n}\sum_{j=i+1}^{n}a_i^2+b_i^2+a_j^2+b_j^2 Σ i=1n Σ j=i+1n ai2 + bi2 + aj2 + bj2 is a fixed value, which can be O ( n 2 ) O(n^2) O(n2) is obtained,
    The problem to deal with now is minimization ∑ i = 1 n ∑ j = i + 1 n 2 ( a i a j + b i b j ) \sum_{i=1}^{n}\sum_{j=i+1}^{n}2(a_ia_j+b_ib_j) Σ i=1n Σ j=i+1n 2(ai aj + bi bj), because a i a j a_ia_j ai # aj # and b i b j b_ib_j bi , bj , is equivalent, so only consider it first
    ∑ i = 1 n ∑ j = i + 1 n a i a j \sum_{i=1}^{n}\sum_{j=i+1}^{n}a_ia_j i=1∑n​j=i+1∑n​ai​aj​
    We need to know ∑ i = 1 n ∑ j = i + 1 n a i a j = ∑ i = 1 n ∑ j = 1 n a i a j − ∑ i = 1 n a i a i 2 = ( ∑ i = 1 n a i ) 2 − ∑ i = 1 n a i 2 2 \sum_{i=1}^{n}\sum_{j=i+1}^{n}a_ia_j=\frac{\sum_{i=1}^{n}\sum_{j=1}^{n}a_ia_j-\sum_{i=1}^{n}a_ia_i}{2}=\\\frac{(\sum_{i=1}^{n}a_i)^2-\sum_{i=1}^{n}a_i^2}{2} i=1 Σ n j=i+1 Σ n ai aj = 2 Σ i=1n Σ j=1n ai aj − ∑ i=1n ai Ai ai = 2 (∑ i=1n ai) 2 − ∑ i=1n ai2 how to prove it? You can consider matrix multiplication. The left side is equivalent to one n × n n\times n n × A triangular region of N matrix (excluding the main diagonal), so how to get it? Obviously, you should use the whole matrix minus the main diagonal element divided by 2, which gives you the formula
  • After knowing this formula, the formula we actually want to minimize is ( ∑ i = 1 n a i ) 2 − ∑ i = 1 n a i 2 + ( ∑ i = 1 n b i ) 2 − ∑ i = 1 n b i 2 = ( ∑ i = 1 n a i ) 2 + ( ∑ i = 1 n b i ) 2 − ∑ i = 1 n a i 2 − ∑ i = 1 n b i 2 (\sum_{i=1}^{n}a_i)^2-\sum_{i=1}^{n}a_i^2+(\sum_{i=1}^{n}b_i)^2-\sum_{i=1}^{n}b_i^2=\\(\sum_{i=1}^{n}a_i)^2+(\sum_{i=1}^{n}b_i)^2-\sum_{i=1}^{n}a_i^2-\sum_{i=1}^{n}b_i^2 (i=1∑n​ai​)2−i=1∑n​ai2​+(i=1∑n​bi​)2−i=1∑n​bi2​=(i=1∑n​ai​)2+(i=1∑n​bi​)2−i=1∑n​ai2​−i=1∑n​bi2​
  • In fact, the back is also a fixed value. You only need to minimize the front. In other words, there is a problem now. Give you two arrays, which can be interchanged a [ i ] a[i] a[i] and b [ i ] b[i] b[i], find ( ∑ i = 1 n a i ) 2 + ( ∑ i = 1 n b i ) 2 (\sum_{i=1}^{n}a_i)^2+(\sum_{i=1}^{n}b_i)^2 Minimum value of (∑ i=1n · ai) 2 + (∑ i=1n · bi) 2
  • Classic dp, set d p [ i ] [ j ] dp[i][j] dp[i][j] is the front i i Can i count up j j j. Then the problem turns into 01 backpack, so the final result is the front i i Can i count up j j j. This is for a [ i ] a[i] a[i], that is ∑ i = 1 n a i \sum_{i=1}^{n}a_i Σ I = the value of 1n ai, then according to the prefix and s u m sum sum can get ∑ i = 1 n b i \sum_{i=1}^{n}b_i Σ i=1n bi, so this minimum value is obtained
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> a(n + 1), b(n + 1);
        for(int i=1;i<=n;i++) cin >> a[i];
        for(int i=1;i<=n;i++) cin >> b[i];
        int ans = 0;
        int mx = 0;
        for(int i=1;i<=n;i++){
            ans -= a[i] * a[i];
            ans -= b[i] * b[i];
            mx += a[i];
            mx += b[i];
            for(int j=i+1;j<=n;j++){
                ans += a[i] * a[i];
                ans += a[j] * a[j];
                ans += b[i] * b[i];
                ans += b[j] * b[j];
            }
        }
        vector<vector<int> > dp(n + 1, vector<int>(mx + 1));
        dp[0][0] = 1;
        for(int i=1;i<=n;i++){
            for(int j=a[i];j<=mx;j++){
                dp[i][j] |= dp[i - 1][j - a[i]];
            }
            for(int j=b[i];j<=mx;j++){
                dp[i][j] |= dp[i - 1][j - b[i]];
            }
        }
        int res = INT_MAX;
        for(int i=0;i<=mx;i++){
            if(dp[n][i]){
                res = min(res, i * i + (mx - i) * (mx - i));                
            }
        }
        cout << ans + res << '\n';
    }
    return 0;
}

E

  • definition c n t x cnt_x cntx is x x x number of occurrences, ask ( c n t x + c n t y ) × ( x + y ) (cnt_x+cnt_y)\times(x+y) (cntx​+cnty​) × Maximum value of (x+y), required ( x , y ) (x,y) (x,y) cannot be b a d   p a i r bad\ pair bad pair
  • The complexity of all numbers in an array with different occurrence times is O ( n ) O(\sqrt n) O(n ) this can be considered as 1,2,3,4... n, which is squared together, so we can consider using the occurrence enumeration. Note that it cannot be b a d   p a i r bad\ pair bad pair, the average time complexity is O ( n n ) O(n\sqrt n) O(nn ​)
#include <bits/stdc++.h>

using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--){
        int n, m;
        cin >> n >> m;
        set<pair<int, int> > s;
        set<int> b;
        map<int, int> mp;
        set<int> a;
        int mx = -1;
        for(int i=0;i<n;i++){
            int x;
            cin >> x;
            a.insert(x);
            mp[x] += 1;
        }
        for(auto i : mp){
            mx = max(mx, i.second);
        }
        vector<vector<int> > g(mx + 1);
        for(auto i : mp){
            g[i.second].push_back(i.first);
            b.insert(i.second);
        }
        for(int i=0;i<=mx;i++) sort(g[i].rbegin(), g[i].rend());
        for(int i=0;i<m;i++){
            int u, v;
            cin >> u >> v;
            if(u > v) swap(u, v);
            s.insert({u, v});
        }
        long long ans = 0;
        for(auto i : a){
            for(auto j : b){
                for(auto k : g[j]){
                    if(i == k) continue;
                    if(!s.count({min(i, k), max(i, k)})){
                        ans = max(ans, 1ll * (i + k) * (mp[i] + j));
                        break;
                    }
                }
            }
        }
        cout << ans << '\n';
    }
    return 0;///
}
  • This code can pass yesterday, but not today. The 77th point is arranged from small to large. This kind of violence will be stuck O ( n 2 ) O(n^2) O(n2), instead of enumerating the number of occurrences, so that the time complexity can return to O ( n ) O(n) O(n)
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--){
        int n, m;
        cin >> n >> m;
        set<int> a;
        map<int, int> mp;
        for(int i=1;i<=n;i++){
            int x;
            cin >> x;
            a.insert(x);
            mp[x] += 1;
        }
        set<int> b;//Essentially different occurrence times
        set<pair<int, int> > s;
        for(int i=0;i<m;i++){
            int u, v;
            cin >> u >> v;
            if(u > v) swap(u, v);
            s.insert({u, v});
        }
        int mx = 0;
        for(auto i : mp){
            mx = max(mx, i.second);
        }
        vector<vector<int> > vis(n + 1);
        for(auto i : mp){
            vis[i.second].push_back(i.first);
            b.insert(i.second);
        }
        for(int i=1;i<=n;i++){
            reverse(vis[i].begin(), vis[i].end());
        }
        ll ans = 0;
        for(int cnt_x=1;cnt_x<=n;cnt_x++){
            for(auto x : vis[cnt_x]){
                for(int cnt_y=1;cnt_y<=cnt_x;cnt_y++){
                    for(auto y : vis[cnt_y]){
                        if(x != y && !s.count({min(x, y), max(x, y)})){
                            ans = max(ans, 1ll * (cnt_x + cnt_y) * (x + y));
                            break;
                        }
                    }
                }
            }
        }
        cout << ans << '\n';
    }
    return 0;
}

Topics: C++ Algorithm