A. Shuffled Equation
排序
代码实现
a, b, c = sorted(map(int, input().split()))
if a*b == c:
print('Yes')
else:
print('No')
B. Who is Missing?
模拟
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<int> a(m);
rep(i, m) cin >> a[i];
vector<int> ans;
for (int i = 1; i <= n; ++i) {
bool exist = false;
for (int na : a) if (na == i) exist = true;
if (!exist) ans.push_back(i);
}
cout << ans.size() << '\n';
for (int x : ans) cout << x << ' ';
return 0;
}
C. Bib
答案为 \(Q(P(Q^{-1}(i)))\)
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n;
cin >> n;
vector<int> p(n), q(n);
rep(i, n) cin >> p[i], p[i]--;
rep(i, n) cin >> q[i], q[i]--;
vector<int> r(n);
rep(i, n) r[q[i]] = i;
rep(i, n) {
int x = r[i];
x = p[x];
x = q[x];
cout << x+1 << ' ';
}
return 0;
}
D. Doubles
可以用哈希预处理出 \(a_j\) 序列中每种数的个数,这样对于任意两个骰子就能做到 \(O(K_i+K_j)\),总复杂度为 \(O(NM)\)
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n;
cin >> n;
vector<int> k(n);
vector<vector<int>> a(n);
rep(i, n) {
cin >> k[i];
a[i].resize(k[i]);
rep(j, k[i]) cin >> a[i][j];
}
double ans = 0;
rep(i, n)rep(j, i) {
double now = 0;
unordered_map<int, int> cnt;
for (int na : a[j]) cnt[na]++;
for (int na : a[i]) now += cnt[na];
now /= k[i];
now /= k[j];
ans = max(ans, now);
}
printf("%.10f\n", ans);
return 0;
}
E. Cables and Servers
显然答案是连通分量的个数减一
操作就是将重边和自环连向其他连通块
代码实现
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, m;
cin >> n >> m;
int ans = n-1;
dsu uf(n);
vector<tuple<int, int, int>> es;
rep(i, m) {
int a, b;
cin >> a >> b;
--a; --b;
if (uf.same(a, b)) {
es.emplace_back(i, a, b);
}
else {
uf.merge(a, b);
ans--;
}
}
cout << ans << '\n';
int v = 0;
rep(i, ans) {
auto [ei, a, b] = es.back(); es.pop_back();
while (uf.same(v, a)) v++;
uf.merge(a, v);
printf("%d %d %d\n", ei+1, a+1, v+1);
}
return 0;
}
F. Insert
倒过来考虑
那么只需将当前数填在剩下没填的位置里的第 \(P_i\) 个位置
可以用树状数组或线段树上二分来实现,复杂度为 2只log 或 1只log
当然也可以直接上平衡树
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
template<typename T=int>
struct BIT {
int n;
vector<T> d;
BIT(int _n=0) {
n = 1;
while (n <= _n+1) n <<= 1;
d.resize(n);
}
void add(int i, T x=1) {
for (i++; i <= n; i += i&-i) {
d[i] += x;
}
}
T sum(int i) {
T x = 0;
for (i++; i; i -= i&-i) {
x += d[i];
}
return x;
}
T sum(int l, int r) {
return sum(r-1) - sum(l-1);
}
int getKth(int k) {
int w = n, i = 0;
while (w) {
if (k > d[i+w]) i += w, k -= d[i];
w >>= 1;
}
return i;
}
};
int main() {
int n;
cin >> n;
vector<int> p(n);
rep(i, n) cin >> p[i];
BIT d(n);
rep(i, n) d.add(i);
vector<int> ans(n);
for (int i = n-1; i >= 0; --i) {
int j = d.getKth(p[i]);
ans[j] = i+1;
d.add(j, -1);
}
rep(i, n) cout << ans[i] << ' ';
return 0;
}
G. Fine Triplets
\(A+C=2B\),可以枚举 \(2B\),然后用 \(\operatorname{FFT}\) 来统计满足条件的 \((A, C)\) 的个数即可,时间复杂度为 \(\mathcal{O}(N\log N)\)
代码实现
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
int main() {
int n;
cin >> n;
const int MX = 1000001;
vector<int> a(MX);
vector<int> s(n);
rep(i, n) {
cin >> s[i];
a[s[i]]++;
}
auto ac = convolution(a, a);
for (int x : s) ac[x*2]--;
rep(i, ac.size()) ac[i] /= 2;
ll ans = 0;
for (int x : s) ans += ac[x*2];
cout << ans << '\n';
return 0;
}
浙公网安备 33010602011771号