A
没动脑。
线段树维护最大子段和。
。
#include "bits/stdc++.h"
using namespace std;
using i64 = int64_t;
template<class Info,
class Merge = plus<Info>>
struct SegmentTree {
const int n;
const Merge merge;
vector<Info> info;
SegmentTree(int n) : n(n), merge(Merge()), info(4 << __lg(n)) {}
SegmentTree(vector<Info> init) : SegmentTree(init.size()) {
function<void(int, int, int)> build = [&](int p, int l, int r) {
if (r - l == 1) {
info[p] = init[l];
return;
}
int m = (l + r) / 2;
build(2 * p, l, m);
build(2 * p + 1, m, r);
pull(p);
};
build(1, 0, n);
}
void pull(int p) {
info[p] = merge(info[2 * p], info[2 * p + 1]);
}
void modify(int p, int l, int r, int x, const Info &v) {
if (r - l == 1) {
info[p] = v;
return;
}
int m = (l + r) / 2;
if (x < m) {
modify(2 * p, l, m, x, v);
} else {
modify(2 * p + 1, m, r, x, v);
}
pull(p);
}
void modify(int p, const Info &v) {
modify(1, 0, n, p, v);
}
Info rangeQuery(int p, int l, int r, int x, int y) {
if (l >= y || r <= x) {
return Info();
}
if (l >= x && r <= y) {
return info[p];
}
int m = (l + r) / 2;
return merge(rangeQuery(2 * p, l, m, x, y), rangeQuery(2 * p + 1, m, r, x, y));
}
Info rangeQuery(int l, int r) {
return rangeQuery(1, 0, n, l, r);
}
};
struct Info {
i64 sum;
i64 lmx;
i64 rmx;
i64 mx;
Info(i64 x = 0) : sum(x), lmx(x), rmx(x), mx(x) {}
};
Info operator+(const Info &a, const Info &b) {
Info res;
res.sum = a.sum + b.sum;
res.lmx = max(a.sum + b.lmx, a.lmx);
res.rmx = max(b.sum + a.rmx, b.rmx);
res.mx = max({a.mx, b.mx, a.rmx + b.lmx});
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
SegmentTree<Info> seg(n);
for (int i = 0; i < n; i++) {
seg.modify(i, a[i]);
}
for (int i = 0; i < n; i++) {
cout << a[i] + seg.rangeQuery(0, i).rmx + seg.rangeQuery(i + 1, n).lmx << " \n"[i == n - 1];
}
return 0;
}
B
打表发现一个东西,然后暴力。
。
#include "bits/stdc++.h"
using namespace std;
using i64 = int64_t;
constexpr int N = 2E5;
int cnt[N + 1];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
cnt[a[i]]++;
}
i64 ans = 0;
for (int i = 1; i <= N; i++) {
for (int j = i; j <= N; j += i) {
int sum = 0;
for (int k = j; k <= N; k += j) {
sum += cnt[k];
}
ans += i64(cnt[i]) * cnt[j] * sum;
}
}
cout << ans << '\n';
return 0;
}
C
#include "bits/stdc++.h"
using namespace std;
using i64 = int64_t;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
if (n < 3) {
cout << "-1\n";
} else {
cout << "CUC" << string(n - 3, 'A') << '\n';
}
return 0;
}
D
来自🐔哥。
我是🐔哥粉丝。
。
#include "bits/stdc++.h"
using namespace std;
using i64 = int64_t;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n), b(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i < n; i++) {
cin >> b[i];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << (a[i] + b[j] > n);
}
cout << '\n';
}
return 0;
}
E
签到。
。
#include "bits/stdc++.h"
using namespace std;
using i64 = int64_t;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m, k;
cin >> n >> m >> k;
if ((n - 1) * (m - 1) < k) {
cout << "-1\n";
return 0;
}
vector a(n, vector<int>(m));
for (int i = 0; i + 1 < n; i++) {
for (int j = 0; j + 1 < m; j++) {
if (k > 0) {
for (int i0 = 0; i0 < 2; i0++) {
for (int j0 = 0; j0 < 2; j0++) {
a[i + i0][j + j0] = 1;
}
}
k--;
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << a[i][j];
}
cout << '\n';
}
return 0;
}
F
dfs 搭配分解法和剪枝。
复杂度不详。
#include "bits/stdc++.h"
using namespace std;
using i64 = int64_t;
vector<int> minp, primes;
void sieve(int n) {
minp.assign(n + 1, 0);
for (int i = 2; i <= n; i++) {
if (minp[i] == 0) {
minp[i] = i;
primes.push_back(i);
}
for (auto p : primes) {
if (i * p > n) {
break;
}
minp[i * p] = p;
if (p == minp[i]) {
break;
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
i64 k;
cin >> n >> k;
sieve(n);
vector<map<int, int>> mp(n);
vector<int> ok(n);
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 ans = 0;
function<void(int, int)> dfs = [&](int x, int p) {
for (auto y : g[x]) {
if (y != p) {
dfs(y, x);
if (ok[y]) {
ok[x] = 1;
continue;
}
for (auto [p, c] : mp[y]) {
mp[x][p] += c;
}
}
}
if (!ok[x]) {
int x0 = x + 1;
while (x0 > 1) {
int p0 = minp[x0];
x0 /= p0;
mp[x][p0]++;
}
i64 res = 1;
for (auto [p, c] : mp[x]) {
if (res * (c + 1) >= k) {
ans++;
ok[x] = 1;
break;
}
res *= (c + 1);
}
} else {
ans++;
}
};
dfs(0, -1);
cout << ans << '\n';
return 0;
}
H
离散化后类似双指针。
。
#include "bits/stdc++.h"
using namespace std;
using i64 = int64_t;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
auto v = a;
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
for (int i = 0; i < n; i++) {
a[i] = lower_bound(v.begin(), v.end(), a[i]) - v.begin();
}
vector<int> c0(n), c1(n);
int tot0 = 0, tot1 = 0;
int l0 = 0, l1 = 0;
i64 ans = 0;
for (int r = 0; r < n; r++) {
if (!c0[a[r]]) {
tot0++;
}
c0[a[r]]++;
if (!c1[a[r]]) {
tot1++;
}
c1[a[r]]++;
while (tot0 > 3) {
c0[a[l0]]--;
if (!c0[a[l0]]) {
tot0--;
}
l0++;
}
while (tot1 > 2) {
c1[a[l1]]--;
if (!c1[a[l1]]) {
tot1--;
}
l1++;
}
ans += l1 - l0;
}
cout << ans << '\n';
return 0;
}
H
类似去年天梯赛 L2-4。
可以 bfs。
。
#include "bits/stdc++.h"
using namespace std;
using i64 = int64_t;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector<string> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
vector t(n + 2, vector<int>(m + 2));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
t[i + 1][j + 1] = (a[i][j] == '*');
}
}
queue<pair<int, int>> q;
q.emplace(0, 0);
t[0][0] = 2;
while (!q.empty()) {
auto [x0, y0] = q.front();
q.pop();
for (auto [dx, dy] : vector<pair<int, int>>{{+1, +0}, {+0, +1}, {-1, +0}, {+0, -1}}) {
int x1 = x0 + dx, y1 = y0 + dy;
if (x1 >= 0 && x1 < n + 2 && y1 >= 0 && y1 < m + 2) {
if (t[x1][y1] == 1) {
t[x1][y1] = 3;
} else if (t[x1][y1] == 0) {
t[x1][y1] = 2;
q.emplace(x1, y1);
}
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << (t[i + 1][j + 1] == 1 && a[i][j] == '*' ? '*' : '.');
}
cout << '\n';
}
return 0;
}
J
数学题。
考虑枚举 。
感觉写的有点假,但是过了。
。
#include "bits/stdc++.h"
using namespace std;
using i64 = int64_t;
vector<int> minp, primes;
void sieve(int n) {
minp.assign(n + 1, 0);
for (int i = 2; i <= n; i++) {
if (minp[i] == 0) {
minp[i] = i;
primes.push_back(i);
}
for (auto p : primes) {
if (i * p > n) {
break;
}
minp[i * p] = p;
if (p == minp[i]) {
break;
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
sieve(1E6);
int n, m;
cin >> n >> m;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a.begin(), a.end());
int mx = a[n - 1];
int g = 0;
for (int i = 1; i < n; i++) {
g = gcd(g, a[i] - a[0]);
}
i64 ans = 0;
for (int i = mx; i <= m; i++) {
int g0 = g;
g0 = gcd(i - a[0], g);
map<int, int> mp;
while (g0 > 1) {
int p = minp[g0];
g0 /= p;
mp[p]++;
}
i64 t = 1;
for (auto [u, v] : mp) {
t *= (v + 1);
}
ans += t;
}
cout << ans << '\n';
return 0;
}