#include<stdio.h> #include<string> #include<iostream> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<set> #include<map> intread(int x = 0, int f = 0, char ch = getchar()) { while (ch < 48or57 < ch) f = ch == 45, ch = getchar(); while(48 <= ch and ch <= 57) x = x * 10 + ch - 48, ch = getchar(); return f ? -x : x; } constint N = 1e6 + 5; int n, a[N];
voidsolve() { n = read(); int max = 1e9 + 5, min = 0; std::set<int> s; for (int i = 1; i <= n; i++) { int opt = read(), x = read(); if (opt == 1) min = std::max(min, x); elseif (opt == 2) max = std::min(max, x); else s.insert(x); } int ans = max - min + 1; for (auto x : s) if (min <= x and x <= max) ans --; ans = std::max(ans, 0); printf("%d\n", ans); }
intmain() { // freopen("A.in", "r", stdin); for (int T = read(); T--; solve()); return0; }
B
给定一个全都是正整数的数组,A 玩家可以先移去最多 k 个元素,随后 B 玩家可以最多给 x 个元素加上负号。A 希望最大化数组元素之和,而 B 希望最小化数组元素之和。如果双方都以最优方式进行游戏,求游戏结束后数组元素的总和。
#include<stdio.h> #include<string> #include<iostream> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<set> #include<map> intread(int x = 0, int f = 0, char ch = getchar()) { while (ch < 48or57 < ch) f = ch == 45, ch = getchar(); while(48 <= ch and ch <= 57) x = x * 10 + ch - 48, ch = getchar(); return f ? -x : x; } constint N = 1e6 + 5; int n, k, x, a[N], pre[N];
voidsolve() { n = read(), k = read(), x = read(); for (int i = 1; i <= n; i++) a[i] = read(); std::sort(a + 1, a + 1 + n, [](int a, int b){return a > b;}); for (int i = 1; i <= n; i++) pre[i] = pre[i - 1] + a[i]; int ans = -1e9 + 5; for (int i = 0; i <= k; i++) { int p = std::min(i + x, n); ans = std::max(ans, -(pre[p] - pre[i]) + pre[n] - pre[p]); } printf("%d\n", ans); }
intmain() { // freopen("A.in", "r", stdin); for (int T = read(); T--; solve()); return0; }
C
把数组切成正好 k 块,然后把每个数都 mod m,问你有多少个 k,存在 m 使得 mod m 后每一块都相同
#include<stdio.h> #include<string> #include<iostream> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<set> #include<map> #include<numeric> intread(int x = 0, int f = 0, char ch = getchar()) { while (ch < 48or57 < ch) f = ch == 45, ch = getchar(); while(48 <= ch and ch <= 57) x = x * 10 + ch - 48, ch = getchar(); return f ? -x : x; } constint N = 2e5 + 5; int n, a[N], ans;
voidjudge(int k) { int cnt = 0, x = 0; for (int i = 1; i <= k; i++) for (int j = i + k; j <= n; j += k) { int val = abs(a[j] - a[j - k]); if (!val) continue; if (!x) x = val, cnt = 1; else x = std::gcd(x, val); } if (x >= 2or cnt == 0) ans++; }
voidsolve() { n = read(), ans = 0; for (int i = 1; i <= n; i++) a[i] = read(); for (int i = 1; i * i <= n; i++) if (n % i == 0) { judge(n / i); if (n / i != i) judge(i); } printf("%d\n", ans); }
intmain() { #ifndef ONLINE_JUDGE freopen("C.in", "r", stdin); #endif for (int T = read(); T--; solve()); return0; }
D
给定一个空数组,两种操作,一种是末尾 push 进去一个数,一种是把自己复制 x 次,push 到末尾