I hope you all enjoyed the contest!
| Predictor | A | B | C | D | E | F | G | H |
|---|---|---|---|---|---|---|---|---|
| AksLolCoding | 800 | 900 | 1000 | 1400 | 1500 | 1800 | 1800 | — |
| ALnQ417 | 800 | 900 | 1100 | 1300 | 1500 | 1600 | — | — |
| bookcat | 800 | 1200 | 1200 | 1500 | 1600 | 1600 | 1600 | 2000 |
| chromate00 | 800 | 800 | 1000 | 1400 | 1400 | 1800 | 1800 | 2200 |
| cry | 800 | 1000 | 1200 | 1600 | 1700 | 2100 | 2100 | 2400 |
| Edeeva | 800 | 800 | 1000 | 1300 | 1400 | 1600 | 1900 | — |
| efishel | 800 | 1000 | 1000 | 1500 | 1500 | 1800 | 1900 | 2200 |
| _Equinox | 800 | 800 | 800 | 1200 | 1500 | 1600 | 1800 | — |
| fatalerror | 800 | 1400 | 1200 | 1600 | 1700 | 1900 | 2000 | 2100 |
| -firefly- | 800 | 800 | 900 | 1400 | 1400 | 1600 | 1800 | 2500 |
| nifeshe | 800 | 800 | 1000 | 1500 | 1600 | 1800 | 1900 | 2400 |
| Non-origination | 800 | 800 | 1000 | 1600 | 1300 | 1600 | 1800 | — |
| reirugan | 800 | 900 | 1200 | 1500 | 1500 | 1800 | 1800 | — |
| temporary1 | 800 | 800 | 900 | 1400 | 1300 | 1800 | 1900 | 2200 |
| white_two | 800 | 800 | 1200 | 1400 | 1400 | 1900 | — | — |
Idea: -firefly-
Preparation: -firefly-
Analysis: temporary1
The step $$$2$$$ doesn't affect step $$$1$$$.
import sys
input = lambda: sys.stdin.readline().rstrip()
ii = lambda: int(input())
mii = lambda: map(int, input().split())
lii = lambda: list(mii())
def solve():
n = ii()
A = lii()
B = lii()
return sum(a - b for a, b in zip(A, B) if a > b) + 1
for _ in range(ii()):
print(solve())
Idea: -firefly-
Preparation: -firefly-
Analysis: reirugan
There are no much difference between the series when $$$n=k$$$ and $$$n=k+1$$$.
Construct the series from the left to the right greedily.
import sys
input = lambda: sys.stdin.readline().rstrip()
ii = lambda: int(input())
mii = lambda: map(int, input().split())
lii = lambda: list(mii())
def solve():
n = ii()
if n == 1:
return [0]
ans = [-1, 3] * (n // 2)
if n % 2:
ans.append(-1)
else:
ans[-1] = 2
return ans
for _ in range(ii()):
print(*solve())
Idea: Tobo
Preparation: Tobo, -firefly-, Friedrich
Analysis: Tobo
Consider the operations modulo $$$k$$$.
import sys
input = lambda: sys.stdin.readline().rstrip()
ii = lambda: int(input())
mii = lambda: map(int, input().split())
lii = lambda: list(mii())
from collections import defaultdict
from random import getrandbits
RD = getrandbits(31)
def solve():
n, k = mii()
A = lii()
B = lii()
cnt = defaultdict(int)
for x in A:
r = x % k
cnt[min(r, k-r) ^ RD] += 1
for x in B:
r = x % k
cnt[min(r, k-r) ^ RD] -= 1
return all(v == 0 for v in cnt.values())
for _ in range(ii()):
print('YES' if solve() else 'NO')
Idea: -firefly-
Preparation: -firefly-
Analysis: __baozii__
What is the minimum diameter achievable?
How are leaves significant?
import sys
input = lambda: sys.stdin.readline().rstrip()
ii = lambda: int(input())
mii = lambda: map(int, input().split())
lii = lambda: list(mii())
def solve():
n = ii()
g = [[] for _ in range(n)]
deg = [0] * n
for _ in range(n-1):
u, v = mii()
u -= 1; v -= 1
g[u].append(v)
g[v].append(u)
deg[u] += 1
deg[v] += 1
if n <= 3:
return 0
c1 = sum(deg[u] == 1 for u in range(n))
mx = max(sum(deg[v] == 1 for v in g[u]) for u in range(n))
return c1 - mx
for _ in range(ii()):
print(solve())
Idea: -firefly-
Preparation: -firefly-
Analysis: __baozii__
import sys
input = lambda: sys.stdin.readline().rstrip()
ii = lambda: int(input())
mii = lambda: map(int, input().split())
lii = lambda: list(mii())
def solve():
n = ii()
A = lii()
B = lii()
if A[-1] != B[-1]:
return False
for i in range(n-2, -1, -1):
if A[i] != B[i] and A[i] ^ A[i+1] != B[i] and A[i] ^ B[i+1] != B[i]:
return False
return True
for _ in range(ii()):
print('YES' if solve() else 'NO')
Idea: efishel, __baozii__
Preparation: -firefly-
Analysis: temporary1, reirugan
The grid possesses a significant property. Try to generate some grids with random $$$a$$$ and $$$b$$$, and understand the distribution of $$$0$$$'s and $$$1$$$'s.
For each point $$$(x, y)$$$, you can derive the answer formula like $$$\min(f(x,y), g(x,y))$$$. Note that $$$\displaystyle\min(f,g)=\frac{f+g}{2}-\frac{|f-g|}{2}$$$
#include <bits/stdc++.h>
using namespace std;
#define f first
#define s second
#define ll long long
#define pii pair<int,int>
#define pli pair<ll,int>
#define pll pair<ll,ll>
#define tiii tuple<int,int,int>
#define tiiii tuple<int,int,int,int>
#define pb push_back
#define eb emplace_back
#define emp emplace
#define mkp make_pair
#define mkt make_tuple
#define vctr vector
#define arr array
#define all(x) x.begin(), x.end()
#define amin(a,b) a = min(a,b)
#define amax(a,b) a = max(a,b)
#define brick(x) cout << #x << " = " << (x) << " | "
#define dbg(x) cout << #x << " = " << (x) << '\n'
#define vdbg(a) cout << #a << " = "; for(auto _x : a)cout << _x << ' '; cout << '\n'
#define adbg(a,n) cout << #a << " = "; for(int _i = 1; _i <= n; ++_i)cout << a[_i] << ' '; cout << '\n'
#define adbg0(a,n) cout << #a << " = "; for(int _i = 0; _i < n; ++_i)cout << a[_i] << ' '; cout << '\n'
mt19937 rng(static_cast<uint32_t>(chrono::steady_clock::now().time_since_epoch().count()));
int uid(int a, int b) { return uniform_int_distribution<int>(a,b)(rng); }
ll uld(ll a, ll b) { return uniform_int_distribution<ll>(a,b)(rng); }
const int MOD = 1e9+7; // 998244353;
int a[200005];
int b[200005];
int c[200005][2];
int d[200005][2];
ll pf[400005][2];
int cnt[400005];
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int tt;
cin >> tt;
while (tt--) {
int n;
cin >> n;
string t;
cin >> t;
for (int i = 1; i <= n; ++i) {
a[i] = (t[i-1] == '1');
}
cin >> t;
for (int i = 1; i <= n; ++i) {
b[i] = (t[i-1] == '1');
}
const int o = n;
for (int i = 0; i <= 2*n; ++i) {
pf[i][0] = 0;
pf[i][1] = 0;
cnt[i] = 0;
}
for (int i = 1; i <= n; ++i) {
c[i][0] = c[i-1][0]+(a[i] == 0);
c[i][1] = c[i-1][1]+(a[i] == 1);
pf[o+c[i][0]-c[i][1]][0] += c[i][0];
pf[o+c[i][0]-c[i][1]][1] += c[i][1];
cnt[o+c[i][0]-c[i][1]] += 1;
}
for (int i = 1; i <= 2*n; ++i) {
pf[i][0] += pf[i-1][0];
pf[i][1] += pf[i-1][1];
cnt[i] += cnt[i-1];
}
for (int i = 1; i <= n; ++i) {
d[i][0] = d[i-1][0]+(b[i] == 0);
d[i][1] = d[i-1][1]+(b[i] == 1);
}
ll ans = 0;
for (int i = 1; i <= n; ++i) {
int z = d[i][1]-d[i][0];
// 0 worth it when delta <= z
ans += d[i][0]*(ll)cnt[o+z]+pf[o+z][0];
ans += d[i][1]*(ll)(n-cnt[o+z])+pf[2*n][1]-pf[o+z][1];
}
cout << ans << '\n';
}
return 0;
}
Idea: -firefly-
Preparation: -firefly-
Analysis: __baozii__
For a set $$$S$$$, how many operations are required to transform $$$S$$$ into $$$S \setminus {\min(S)}$$$?
$$$S$$$ can be represented as a binary number (though very large).
How to calculate the answer when elements in $$$S$$$ are very large?
MOD = 10 ** 9 + 7
dp = [0] * 31
dp[0] = 1
for i in range(1, 31):
dp[i] = i + 1
for j in range(i):
dp[i] = dp[i] * dp[j] % MOD
def dfs(v, k):
if k == 0:
return 1
ans = v + 1
v = min(v - 1, 30)
k -= 1
for j in range(v + 1):
if k >= 1 << j:
ans = ans * dp[j] % MOD
k -= 1 << j
else:
ans = ans * dfs(j, k) % MOD
break
return ans
for _ in range(int(input())):
n, k = map(int, input().split())
s = list(map(int, input().split()))
for i in range(n):
s[i] -= 1
s.sort()
ans = 1
for v in s:
if v <= 30 and k >= 1 << v:
k -= 1 << v
ans = ans * dp[v] % MOD
else:
ans = ans * dfs(v, k) % MOD
break
print(ans)
Idea: __baozii__, -firefly-
Preparation: -firefly-
Analysis: -firefly-
Let's consider an easier problem: how do we find one coprime pair from $$$a$$$?
If there exists one coprime pair, it means there exists an $$$i$$$ such that
In other words, there are at least one other indices $$$j$$$ such that $$$\gcd(a_i, a_j)=1$$$.
Therefore, we strengthen the problem that we need to find $$$\displaystyle\sum_{j=1}^{n}[\gcd(a_i, a_j)=1]$$$ for each $$$i$$$. Here, we introduce two ways to solve the formula.
In the following discussion, we denote $$$f(d)$$$ to be the count of elements in $$$a$$$ divisible by $$$d$$$. We can precompute $$$f(1), f(2), \dots, f(m)$$$ in $$$O(m\log m)$$$ time using harmonic trick.
For each $$$a_i$$$, find the set of distinct prime factors of $$$a_i$$$. Let's call this set $$$P_i$$$. For each prime factor $$$p_k \in P_i$$$, let $$$S_k$$$ be the set of elements in the array $$$a$$$ that are divisible by $$$p_k$$$.
Any number that is NOT coprime to $$$a_i$$$ must share at least one prime factor with $$$a_i$$$, so it must belongs to the set union $$$S_1 \cup S_2 \cup \dots \cup S_k$$$. By PIE we can calculate the size of the union:
Here:
- $$$|S_r|$$$ is the count of elements in $$$a$$$ divisible by $$$p_r$$$, which is $$$f(p_r)$$$.
- $$$|S_r \cap S_s|$$$ is the count of elements in $$$a$$$ divisible by both $$$p_r$$$ and $$$p_s$$$, that is, divisible by $$$p_rp_s$$$, which is $$$f(p_rp_s)$$$.
- Similarly, $$$|S_r \cap S_s \cap S_t|$$$ is $$$f(p_rp_sp_t)$$$.
Since $$$f(d)$$$ has been precomputed, we can compute $$$|S_1 \cup S_2 \cup \dots \cup S_k|$$$ for each $$$i$$$ in $$$O(2^{|P_i|})$$$ time. Because $$$2 \times 3 \times 5 \times 7 \times 11 \times 13 \times 17 \times 19 = 9699690 \gt 10^6$$$, the size of $$$P_i$$$ won't exceed $$$7$$$. Therefore, the operation number is roughly $$$2^7 \cdot n \le 3 \cdot 10^7$$$, which is acceptable.
After finding the count of elements that is NOT coprime to $$$a_i$$$, we can then easily obtain $$$\displaystyle\sum_{j=1}^{n}[\gcd(a_i, a_j)=1]$$$ by subtraction.
Another advanced approach to find the result is Mobius inversion. We will assume that you know the definition and property of mobius function $$$\mu(n)$$$ in the following discussion.
Since we know that $$$\displaystyle[\gcd(x, y) = 1] = \sum_{d|\gcd(x, y)}\mu(d)$$$, we can expand the orginal formula as:
Let's swap the order of summation and get
Because $$$d | \gcd(a_i, a_j)$$$ is equivalent to $$$d|a_i$$$ and $$$d|a_j$$$, we can simplify the formula to
Thus, we can enumerate the divisors of $$$a_i$$$ for each $$$i$$$ and compute the summation above by brute force, which yields a $$$O(n\sqrt{m})$$$ or $$$O(nd(n))$$$ time.
Let's build a graph $$$G$$$ where vertex $$$i$$$ and $$$j$$$ has an undirected edge if and only if $$$\gcd(a_i, a_j) = 1$$$. The problem becomes finding a match of size $$$2$$$ in the graph. However, we only has each vertex's degrees based on the discussion above. How do we find the match only based on degrees?
We use a greedy approach to obtain the match of size $$$2$$$. Let's say $$$G$$$ has at least one edge.
- Choose a vertex $$$u$$$ with the maximum degree.
- From all vertices that is connected to $$$u$$$, pick a vertex $$$v$$$ with the minimum degree.
- Remove vertices $$$u$$$ and $$$v$$$ and their associated edges from $$$G$$$ to get a new graph $$$G^\prime$$$.
- If there are at least one remaining edge in $$$G^\prime$$$, $$$G$$$ has a match of size $$$2$$$ that contains $$$(u, v)$$$ and the remaining edge. Otherwise, it doesn't have a match of size $$$2$$$.
We will prove that if $$$G^\prime$$$ contains no edges, $$$G$$$ doesn't have a match of size $$$2$$$.
Because $$$G^\prime$$$ has no edge, all of the vertices that is not isolated in $$$G$$$ connect to $$$u$$$, $$$v$$$ or both. It means $$$G$$$ has only one connected component that contains more than two vertices. To make disucssion easier, we will use $$$G$$$ to refer to $$$G$$$'s major connect component. That means all of the vertices other than $$$u$$$ and $$$v$$$ have a degree of $$$1$$$ or $$$2$$$ in $$$G$$$.
- If all vertices other than $$$u$$$ and $$$v$$$ have a degree of $$$1$$$. If at least one vertex is connected to $$$u$$$, the minimum degree that $$$u$$$'s connected vertices becomes $$$1$$$. Since the algorithm choose $$$v$$$ with the minimum degree, $$$v$$$ also has a degree of $$$1$$$, so all vertices are connected to $$$u$$$. In this case, $$$G$$$ is a star-shaped tree, which doesn't have a match of size $$$2$$$ for obvious reason. On the other hand, if all vertices are connected to $$$v$$$, the degree of $$$v$$$ is greater than $$$u$$$, which is impossible become the degree of $$$u$$$ is maximum.
- If exactly one vertex other than $$$u$$$ and $$$v$$$ has a degree of $$$2$$$, it must connect to both $$$u$$$ and $$$v$$$. Similar to the discussion above, we can prove that no other vertex can be connected to either $$$u$$$ or $$$v$$$. In this case, $$$G$$$ is a three-vertex loop, or $$$K_3$$$, which doesn't have a match of size $$$2$$$.
- If more than two vertices other than $$$u$$$ and $$$v$$$ have a degree of $$$2$$$, it means $$$v$$$ has a degree of more than $$$3$$$. Let's denote a vertex that connects to both $$$u$$$ and $$$v$$$ as $$$w$$$, then $$$\mathrm{deg}(w) = 2 \lt 3 \le \mathrm{deg}(v)$$$. Because $$$w$$$ is also connected to $$$u$$$, it contradicts to the step $$$2$$$ of the algorithm.
For our problem, for each $$$i$$$, the degree is $$$\displaystyle\sum_{j=1}^{n}[\gcd(a_i, a_j)=1] - [a_i = 1]$$$. We can then brute force to find the first edge, remove it, and then try to find the second edge.
#include <bits/stdc++.h>
using i64 = long long;
constexpr int V = 1e6 + 10;
std::array<int, V> mu, comp;
std::vector<int> primes;
void solve() {
int n, m = 0;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++i) {
std::cin >> a[i];
m = std::max(m, a[i]);
}
std::vector<int> mul(m+1), deg(n), mp(m+1);
for (int i = 0; i < n; ++i) {
mp[a[i]]++;
}
for (int j = 1; j <= m; ++j) {
for (int x = j; x <= m; x += j) {
mul[j] += mp[x];
}
}
for (int i = 0; i < n; ++i) {
for (int j = 1; j * j <= a[i]; ++j) {
if (a[i] % j == 0) {
deg[i] += mu[j] * mul[j];
if (j * j < a[i]) {
deg[i] += mu[a[i] / j] * mul[a[i] / j];
}
}
}
if (a[i] == 1) --deg[i];
}
std::array<int, 4> ans;
int u = 0, v = 0, mind = INT32_MAX;
for (int i = 1; i < n; ++i) {
if (deg[i] > deg[u]) {
u = i;
}
}
if (!deg[u]) {
std::cout << "0\n";
return;
}
deg[u] = 0;
for (int i = 0; i < n; ++i) {
if (i == u) continue;
if (std::gcd(a[i], a[u]) == 1) {
--deg[i];
if (mind > deg[i]) {
mind = deg[i];
v = i;
}
}
}
ans[0] = u;
ans[1] = v;
deg[v] = 0;
for (int i = 0; i < n; ++i) {
if (i == u || i == v) continue;
if (std::gcd(a[i], a[v]) == 1) {
--deg[i];
}
}
u = 0;
for (int i = 1; i < n; ++i) {
if (deg[i] > deg[u]) {
u = i;
}
}
if (!deg[u]) {
std::cout << "0\n";
return;
}
v = -1;
for (int i = 0; i < n; ++i) {
if (i == u || !deg[i]) continue;
if (std::gcd(a[i], a[u]) == 1) {
v = i;
break;
}
}
assert(v >= 0);
ans[2] = u; ans[3] = v;
for (int i = 0; i < 4; ++i) {
std::cout << ans[i] + 1 << " \n"[i == 3];
}
}
int main() {
std::cin.tie(nullptr)->sync_with_stdio(false);
int T = 1;
std::cin >> T;
mu[1] = 1;
for (int i = 2; i < V; ++i) {
if (!comp[i]) {
primes.emplace_back(i);
mu[i] = -1;
}
for (auto p: primes) {
int q = i * p;
if (q >= V) break;
comp[q] = true;
if (i % p == 0) {
mu[q] = 0;
break;
} else {
mu[q] = -mu[i];
}
}
}
while (T--) solve();
return 0;
}



