Codeforces 1556, Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2)
阿新 • • 發佈:2021-08-30
終於藍了嗚嗚嗚
原來兩場四題就能上分 以後不棄賽了
A.
注意到2, 3操作不改變總和,1操作使得總和加上了一個偶數,故直接判斷總和是否為偶數即可。如果和為偶數,只要判斷c和d是否相等即可。注意0要判一下
B.
先判一下奇數和偶數的個數,在按順序分配位置就行。如果奇數和偶數個數相等,還得列舉奇數先放還是偶數先放。注意開ll。
C.
莫名其妙地ac了,不是很懂。
首先列舉左端點l和右端點r,用函式check(l,r)統計這兩個端點的貢獻(在l處開始,r處結束的合法括號序列的數量)。假設每一個左括號為1,右括號為-1,對序列求個字首和,方便判斷是否合法。
所有的從l開始,r結束的合法括號序列,不一定用了l和r中的每一個左右括號。
首先計算d=sum[r]-sum[l-1],以得出左右兩邊是否有多餘的括號,我們要捨去。之後再列舉\(l+1\)到\(r-1\)的每一個位置\(i\),他們必須滿足\(sum[i]-sum[l-1]>=0\).統計這個差值的最小值,記為mx,其表示左邊l處最多能有幾個括號多出來。那麼答案至多有mx+1.注意當d>0時,這個值要減去d後才能用於更新mx。
之後保險起見,還得和左邊能貢獻的左括號數量,右邊能貢獻的右括號數量取min,注意此時也要把d的偏差加上去,具體見程式碼。
// Problem: C. Compressed Bracket Sequence // Contest: Codeforces - Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2) // URL: https://codeforces.com/contest/1556/problem/C // Memory Limit: 256 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std; const int maxn = 1e5 + 7; #define ll long long int rd() { int s = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();} while (c >= '0' && c <= '9') {s = s * 10 + c - '0'; c = getchar();} return s * f; } int n, m, k; ll tot; ll c[maxn], ans, sum[maxn]; ll check(int l, int r) { ll d = sum[r]-sum[l-1], mx = 99999999999999999ll; for (int i = l+1; i < r; i += 2) { if (d <= 0) mx = min(mx, sum[i]-sum[l-1]); if (d > 0) mx = min(mx, sum[i]-d-sum[l-1]); } if (mx < 0) return 0; //if (mx == 0) return 1; if (d == 0) return min(c[l], min(mx + 1ll, -c[r])); if (d < 0) return min(c[l], min(mx + 1ll, -c[r]+d)); if (d > 0) return min(c[l]-d, min(mx+1ll, -c[r])); } int main() { n = rd(); for (int i = 1; i <= n; i++) { c[i] = rd(); if (i % 2 == 0) c[i] = -c[i]; sum[i] = sum[i-1]+c[i]; } for (int l = 1; l <= n; l += 2) { for (int r = l+1; r <= n; r += 2) { ans += check(l, r); } } printf("%lld\n", ans); }
D.
\(a+b=a\&b+a|b\),用\(a+b,a+c,b+c\)可以求出\(abc\),已知\(a\)和\(a\&b+a|b\)可以求\(b\),這樣直接求出所有的\(a[i]\)就行。
// Problem: D. Take a Guess // Contest: Codeforces - Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2) // URL: https://codeforces.com/contest/1556/problem/D // Memory Limit: 256 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std; const int maxn = 1e4 + 7; #define ll long long int rd() { int s = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();} while (c >= '0' && c <= '9') {s = s * 10 + c - '0'; c = getchar();} return s * f; } int n, m, k, tot; ll a[maxn]; typedef pair<int, int> pii; #define mk make_pair ll getPlus(int i, int j) { printf("or %d %d\n", i, j); fflush(stdout); ll orij = rd(); printf("and %d %d\n", i, j); fflush(stdout); ll andij = rd(); return orij + andij; } void get(int i, int j, int k) { ll pij = getPlus(i, j); ll pjk = getPlus(j, k); ll pik = getPlus(i, k); a[i] = (pij - pjk + pik) / 2ll; a[j] = (pjk - pik + pij) / 2ll; a[k] = (pik - pij + pjk) / 2ll; } int main() { n = rd(); k = rd(); for (int i = 1; i <= n; i += 3) { if (i + 2 > n) break; get(i, i+1, i+2); } if (n % 3 == 1) { ll p1 = getPlus(1, n); a[n] = p1 - a[1]; } if (n % 3 == 2) { ll p1 = getPlus(1, n-1); a[n-1] = p1 - a[1]; ll p2 = getPlus(1, n); a[n] = p2 - a[1]; } sort(a+1, a+n+1); printf("finish %lld\n", a[k]); return 0; //fflush(stdout); }
注意每一行輸出之後要立刻fflush(stdout);