A 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <bits/stdc++.h> using namespace std;using i64 = long long ;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int n; cin >> n; for (int i = n; i >= 0 ; i--) { cout << i << '\n' ; } return 0 ; }
B 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <bits/stdc++.h> using namespace std;using i64 = long long ;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); string s; cin >> s; if (!(s[0 ] >= 'A' && s[0 ] <= 'Z' && s[s.size () - 1 ] >= 'A' && s[s.size () - 1 ] <= 'Z' )) { cout << "No\n" ; return 0 ; } if (s.size () != 8 ) { cout << "No\n" ; return 0 ; } for (int i = 1 ; i <= 6 ; i++) { if (!(s[i] >= '0' && s[i] <= '9' )) { cout << "No\n" ; return 0 ; } } if (s[1 ] == '0' ) { cout << "No\n" ; return 0 ; } cout << "Yes\n" ; return 0 ; }
C 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <bits/stdc++.h> using namespace std;using i64 = long long ;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); i64 n, T; cin >> n >> T; vector<i64> a (n + 1 ) ; for (int i = 1 ; i <= n; i++) { cin >> a[i]; } i64 s = accumulate (a.begin () + 1 , a.end (), 0LL ); T %= s; if (s >= T) { i64 o = 0 ; for (int i = 1 ; i <= n; i++) { if (T < a[i]) { cout << i << ' ' << T << '\n' ; return 0 ; } T -= a[i]; } } return 0 ; }
D - Max Multiple 第一次看写了个dfs T爆了,仔细想想,应该用dp
dp[i][j][k] 三维, 表示前i位取了j个数字mod d 等于k的最大和,则
当当前这一位不取, dp[i + 1][j][k] = max(dp[i][j][k]);
否则,如果这一位取了,更新下一位取了j + 1个的时候的值,同时注意mod的数字(详细见代码)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <bits/stdc++.h> using namespace std;using i64 = long long ;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); i64 n, k, d; cin >> n >> k >> d; vector<i64> a (n + 1 ) ; for (int i = 1 ; i <= n; i++) { cin >> a[i]; } vector dp (n + 2 , vector (k + 1 , vector<i64> (d + 1 , -1 ))) ; dp[1 ][0 ][0 ] = 0 ; for (int i = 1 ; i <= n; i++) { for (int j = 0 ; j <= k; j++) { for (int g = 0 ; g < d; g++) { if (dp[i][j][g] == -1 ) continue ; dp[i + 1 ][j][g] = max (dp[i + 1 ][j][g], dp[i][j][g]); if (j != k) { dp[i + 1 ][j + 1 ][(g + a[i]) % d] = max (dp[i + 1 ][j + 1 ][(g + a[i]) % d], dp[i][j][g] + a[i]); } } } } cout << dp[n + 1 ][k][0 ] << '\n' ; return 0 ; }
E - Least Elements
给定一个长度为 NN 的整数序列 A=(A1,…,AN)A=(A1,…,AN) ,以及整数 MM 和 KK 。 对于每个 i=1,…,N−M+1i=1,…,N−M+1 ,求解如下独立问题。 在 MM 整数 Ai,Ai+1,…,Ai+M−1Ai,Ai+1,…,Ai+M−1 的排序列表中按升序查找前一个 KK 值的和。
思路: 第一反应是可持久化线段树,维护一个当前位置和区间和,每次查询第(区间长度 - 需要的数字数量小)的数字,合并的时候统计下区间内比当前小的数字的答案。
补题思路: 对顶堆: 开两个堆,将当前满足条件的数置于L中,候选的置于R中,维护一个滑动窗口,每次更新一个值时:将左侧的元素删除,右侧的元素加入,统计最小的k个数的和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #include <bits/stdc++.h> using namespace std;using i64 = long long ;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int n, m, k; cin >> n >> m >> k; vector<i64> a (n + 1 ) ; for (int i = 1 ; i<= n; i++) { cin >> a[i]; } multiset<i64> l, r; auto pop_back = [&](multiset<i64>& x) -> i64 { auto it = prev (x.end ()); i64 val = *it; x.erase (it); return val; }; auto pop_front = [&](multiset<i64>& x) -> i64 { auto it = x.begin (); i64 val = *it; x.erase (it); return val; }; i64 sum = 0 ; for (int i = 1 ; i <= m; i++) { sum += a[i]; l.insert (a[i]); while (l.size () > k) { int v = pop_back (l); r.insert (v); sum -= v; } } for (int i = 1 ; i <= n - m + 1 ; i++) { cout << sum << " " ; if (k == m) { sum += a[i + m] - a[i]; } else { l.insert (a[i + m]); sum += a[i + m]; int v = pop_back (l); sum -= v; r.insert (v); if (r.find (a[i]) != r.end ()) { r.erase (r.find (a[i])); } else { l.erase (l.find (a[i])); sum -= a[i]; int v = pop_front (r); sum += v; l.insert (v); } } } return 0 ; }
F - Xor Minimization
如果所有数字的 i 位上都是0, 那么这一位一定填上 0
如果所有数字 i位上都是 1, 那么这一位一定填上1(结果这一位一定是0)
如果某一位上有 0 又有 1, 如 11000, 11100, 第三位不论别的怎么填,异或后答案这一位上总会是1,dfs即可球的答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 #include <bits/stdc++.h> using namespace std;using i64 = long long ;struct Trie { int n, cnt; vector<array<int , 2>> ch; Trie () {} Trie (int n) : n (n), cnt (0 ) { ch.assign (n, {}); } void insert (int x) { int p = 0 ; for (int i = 30 ; i >= 0 ; i--) { int g = ((x >> i) & 1 ); if (ch[p][g] == 0 ) { ch[p][g] = ++cnt; } p = ch[p][g]; } } int dfs (int pos, int x) { if (pos == -1 ) { return 0 ; } if (ch[x][0 ] == 0 ) { return dfs (pos - 1 , ch[x][1 ]); } else if (ch[x][1 ] == 0 ) { return dfs (pos - 1 , ch[x][0 ]); } else { return min (dfs (pos - 1 , ch[x][0 ]), dfs (pos - 1 , ch[x][1 ])) | (1LL << pos); } } }; int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int n; cin >> n; Trie tr (5e6 ) ; vector<int > a (n + 1 ) ; for (int i = 1 ; i <= n; i++) { cin >> a[i]; tr.insert (a[i]); } int ans = tr.dfs (30 , 0 ); cout << ans << '\n' ; return 0 ; }