A
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s, t;
cin >> s >> t;
i64 x = 0, y = 0;
for (auto &si : s) {
x = x * 2 + si - '0';
}
for (auto &ti : t) {
y = y * 2 + ti - '0';
}
if (x == 0 && y != x) {
cout << "-1\n";
} else {
cout << abs(x - y) << '\n';
}
return 0;
}
D
变成全 或全 。
C++ Code
#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;
vector<string> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
string s;
int c0 = 0, c1 = 0;
for (int i = 0; i < n; i++) {
s += a[0][i] ^ 1;
c0 += (a[0][i] == '0');
c1 += (a[i][0] == '0');
}
for (int i = 0; i < n; i++) {
if (a[i] != s && a[i] != a[0]) {
cout << "-1\n";
return 0;
}
}
cout << min(n - c1, c1) + min(n - c0, c0) << '\n';
return 0;
}
E
记 为从 到 途中所能经过的最多边(到达 就停下来), 为从 到 的最短路,若 则 Yes。
G
可以二分 ,枚举每个点作为靠近对称点的点算出对应的最大中心对称正方形(边长分奇偶),。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
const int B[] = {114514, 223333};
const int P = 2147483629;
i64 *p[2];
void init(int N) {
p[0] = new i64 [N];
p[1] = new i64 [N];
p[0][0] = p[1][0] = 1;
for (int i = 1; i <= N; i++) {
p[0][i] = p[0][i - 1] * B[0] % P;
p[1][i] = p[1][i - 1] * B[1] % P;
}
}
struct StringHash2D {
int n, m;
vector<vector<i64>> h;
StringHash2D(const vector<string> &a) {
n = a.size();
m = (n == 0 ? 0 : a[0].size());
h.assign(n + 1, {});
for (int i = 0; i <= n; i++) {
h[i].assign(m + 1, 0);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
h[i + 1][j + 1] = (h[i][j + 1] * B[0] % P + h[i + 1][j] * B[1] % P +
(P - h[i][j]) * B[0] % P * B[1] % P + a[i][j]) % P;
}
}
}
i64 get(int x1, int y1, int x2, int y2) { // p1 = (x1, y1) p2 = (x2, y2) [p1, p2)
return (h[x2][y2] + h[x1][y1] * p[0][x2 - x1] % P * p[1][y2 - y1] % P +
(P - h[x1][y2]) * p[0][x2 - x1] % P + (P - h[x2][y1]) * p[1][y2 - y1] % P) % P;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
init(2E3);
int n, m;
cin >> n >> m;
vector<string> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
auto b = a;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
b[i][j] = a[n - 1 - i][m - 1 - j];
}
}
StringHash2D hs1(a), hs2(b);
auto same = [&](int x1, int y1, int x2, int y2) {
return hs1.get(x1, y1, x2, y2) == hs2.get(n - x2, m - y2, n - x1, m - y1);
};
i64 ans = 0;
// odd
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int l = 1, r = min(min(i + 1, n - i), min(j + 1, m - j));
while (l <= r) {
int x = (l + r) >> 1;
if (same(i - x + 1, j - x + 1, i + x, j + x)) {
l = x + 1;
} else {
r = x - 1;
}
}
ans += l - 1;
}
}
// even
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
int l = 1, r = min(min(i, n - i), min(j, m - j));
while (l <= r) {
int x = (l + r) >> 1;
if (same(i - x, j - x, i + x, j + x)) {
l = x + 1;
} else {
r = x - 1;
}
}
ans += l - 1;
}
}
cout << ans << '\n';
return 0;
}
H
哥德巴赫猜想在题目范围内正确。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
bool isprime(int x) {
if (x < 2) {
return false;
}
for (int i = 2; i64(i) * i <= x; i++) {
if (x % i == 0) {
return false;
}
}
return true;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n);
i64 sum = 0;
for (int i = 0; i < n;i++) {
cin >> a[i];
sum += a[i];
}
if (n == 1) {
cout << (isprime(a[0]) ? "Yes" : "No") << '\n';
} else if (n == 2) {
if (sum % 2) {
cout << (isprime(sum - 2) ? "Yes" : "No") << '\n';
} else {
cout << (sum > 2 ? "Yes" : "No") << '\n';
}
} else {
cout << (sum >= 2 * n ? "Yes" : "No") << '\n';
}
return 0;
}
I
答案为 的距离加转换颜色次数。
将 看成 和 。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
cin >> n >> q;
vector<i64> c(n);
for (int i = 0; i < n; i++) {
cin >> c[i];
}
vector<vector<int>> g(n);
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
u--, v--;
g[u].push_back(v);
g[v].push_back(u);
}
int lg = __lg(n);
vector<int> dep(n);
vector<vector<int>> p(lg + 1, vector<int>(n, -1));
vector<vector<i64>> sum(lg + 1, vector<i64>(n));
auto f = p;
function<void(int, int)> dfs = [&](int cur, int pre) {
for (int i = 0; (2 << i) <= dep[cur]; i++) {
p[i + 1][cur] = p[i][p[i][cur]];
sum[i + 1][cur] = sum[i][p[i][cur]] & sum[i][cur];
}
int u = cur;
i64 col = c[u];
for (int i = lg; i >= 0; i--) {
if (col & sum[i][u]) {
col &= sum[i][u];
u = p[i][u];
}
}
f[0][cur] = u;
for (int i = 0; (2 << i) <= dep[cur]; i++) {
f[i + 1][cur] = f[i][f[i][cur]];
}
for (auto &nex : g[cur]) {
if (nex != pre) {
p[0][nex] = cur;
dep[nex] = dep[cur] + 1;
sum[0][nex] = c[cur] & c[nex];
dfs(nex, cur);
}
}
};
auto lca = [&](int x, int y) {
if (dep[x] < dep[y]) {
swap(x, y);
}
for (int i = lg; i >= 0; i--) {
if (dep[x] - dep[y] >= (1 << i)) {
x = p[i][x];
}
}
if (x == y) {
return x;
}
for (int i = lg; i >= 0; i--) {
if(p[i][x] != p[i][y]) {
x = p[i][x];
y = p[i][y];
}
}
return p[0][x];
};
dfs(0, -1);
auto getCol = [&](int u, int v) {
i64 res = c[u];
for (int i = lg; i >= 0; i--) {
if (dep[u] - dep[v] >= (1 << i)) {
res &= sum[i][u];
u = p[i][u];
}
}
return res;
};
for (int i = 0; i < q; i++) {
int u, v;
cin >> u >> v;
u--, v--;
int m = lca(u, v);
int ans = dep[u] + dep[v] - 2 * dep[m];
for (int i = lg; i >= 0; i--) {
if (dep[f[i][u]] > dep[m]) {
ans += 1 << i;
u = f[i][u];
}
if (dep[f[i][v]] > dep[m]) {
ans += 1 << i;
v = f[i][v];
}
}
i64 x = getCol(u, m);
i64 y = getCol(v, m);
if (!x || !y) {
cout << "-1\n";
} else {
if (!(x & y)) {
ans++;
}
cout << ans << '\n';
}
}
return 0;
}
J
跑个拓扑序。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector<vector<int>> g(n);
vector<int> deg(n);
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
u--, v--;
g[u].push_back(v);
deg[v]++;
}
vector<int> ans;
for (int i = 0; i < n; i++) {
if (!deg[i]) {
ans.push_back(i);
}
}
for (int i = 0; i < (int) ans.size(); i++) {
int cur = ans[i];
for (auto &nex : g[cur]) {
if (!--deg[nex]) {
ans.push_back(nex);
}
}
}
if (ans.size() == n) {
cout << "1\n";
for (int i = 0; i < n; i++) {
cout << ans[i] + 1 << " \n"[i == n - 1];
}
} else {
cout << "2\n";
for (int i = 1; i <= n; i++) {
cout << i << " \n"[i == n];
}
for (int i = n; i >= 1; i--) {
cout << i << " \n"[i == n];
}
}
return 0;
}