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+1nai2+bi2+aj2+bj2+2(aiaj+bibj)
- 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∑nj=i+1∑naiaj
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∑nai)2−i=1∑nai2+(i=1∑nbi)2−i=1∑nbi2=(i=1∑nai)2+(i=1∑nbi)2−i=1∑nai2−i=1∑nbi2
- 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; }