Codeforces Round #731 (Div. 3)
Codeforces Round #731 (Div. 3)
A - Shortest Path with Obstacle
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int _;
for (cin >> _; _; --_) {
pair<int, int> pos[3];
for (int i = 0; i < 3; ++i)
cin >> pos[i].first >> pos[i].second;
if (pos[0].first == pos[1].first && pos[0].first == pos[2].first) {
if (pos[2].second > pos[0].second && pos[2].second < pos[1].second)
cout << pos[1].second - pos[0].second + 2 << '\n';
else if (pos[2].second > pos[1].second && pos[2].second < pos[0].second)
cout << pos[0].second - pos[1].second + 2 << '\n';
else
cout << abs(pos[0].second - pos[1].second) << '\n';
} else if (pos[0].second == pos[1].second && pos[0].second == pos[2].second) {
if (pos[2].first > pos[0].first && pos[2].first < pos[1].first)
cout << pos[1].first - pos[0].first + 2 << '\n';
else if (pos[2].first > pos[1].first && pos[2].first < pos[0].first)
cout << pos[0].first - pos[1].first + 2 << '\n';
else
cout << abs(pos[0].first - pos[1].first) << '\n';
}
else cout << abs(pos[0].first - pos[1].first) + abs(pos[0].second - pos[1].second) << '\n';
}
return 0;
}
B - Alphabetical Strings
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int _;
for (cin >> _; _; --_) {
string s;
cin >> s;
deque<char> du;
for (auto &c : s)
du.emplace_back(c);
bool f = 1;
for (int i = s.size() - 1; !du.empty() && f; --i)
if (du.front() == 'a' + i)
du.pop_front();
else if (du.back() == 'a' + i)
du.pop_back();
else
f = 0;
cout << (f ? "YES" : "NO") << '\n';
}
return 0;
}
C - Pair Programming
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int _;
for (cin >> _; _; --_) {
int n, m, k;
cin >> k >> n >> m;
queue<int> x, y, ans;
for (int i = 0; i < n; ++i) {
int a;
cin >> a;
x.emplace(a);
}
for (int i = 0; i < m; ++i) {
int a;
cin >> a;
y.emplace(a);
}
while (!x.empty() || !y.empty()) {
if (!x.empty() && x.front() == 0) {
ans.emplace(0);
x.pop();
++k;
} else if (!y.empty() && y.front() == 0) {
ans.emplace(0);
y.pop();
++k;
} else if (!x.empty() && x.front() <= k) {
ans.emplace(x.front());
x.pop();
} else if (!y.empty() && y.front() <= k) {
ans.emplace(y.front());
y.pop();
} else
break;
}
if (!x.empty() || !y.empty())
cout << "-1\n";
else {
while (!ans.empty()) {
cout << ans.front() << ' ';
ans.pop();
}
cout << '\n';
}
}
return 0;
}
D - Co-growing Sequence
\(b_0 = 1\), 剩下的模拟
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int _;
for (cin >> _; _; --_) {
int n;
cin >> n;
vector<int> a(n);
for (auto &i : a)
cin >> i;
for (int i = 0, ls = a[0]; i < n; ++i) {
int cur = 0;
for (int j = 29; ~j; --j)
if ((ls >> j & 1) && !(a[i] >> j & 1))
cur ^= 1 << j;
cout << cur << ' ';
ls = a[i] ^ cur;
}
cout << '\n';
}
return 0;
}
E - Air Conditioners
考虑在空调右边的各自的温度为
\(i - pos[j] + tem[j] = i + (tem[j] - pos[j])\)
扫一遍维护\(min(tem[j] - pos[j])\)即可
空调在左边同理维护空调位置和空调温度的和即可, 最后取个最小值
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int _;
for (cin >> _; _; --_) {
int n, k;
cin >> n >> k;
vector<pair<int, int>> b(k);
for (auto &i : b)
cin >> i.first;
for (auto &i : b)
cin >> i.second;
sort(b.begin(), b.end());
vector<int> ans(n + 1, 2e9);
for (int i = 1, j = 0, g = -1; i <= n; ++i)
if (~g) {
if (j < k && b[j].first == i) {
if (b[j].second - i < b[g].second - b[g].first)
g = j;
++j;
}
ans[i] = i + b[g].second - b[g].first;
} else if (j < k && b[j].first == i) {
g = j++;
ans[i] = i + b[g].second - b[g].first;
}
for (int i = n, j = k - 1, g = -1; i; --i)
if (~g) {
if (j != -1 && b[j].first == i) {
if (i + b[j].second < b[g].second + b[g].first)
g = j;
--j;
}
ans[i] = min(ans[i], b[g].second + b[g].first - i);
} else if (j != -1 && b[j].first == i) {
g = j--;
ans[i] = min(ans[i], b[g].second + b[g].first - i);
}
for (int i = 1; i <= n; ++i)
cout << ans[i] << char(" \n"[i == n]);
}
return 0;
}
F - Array Stabilization (GCD version)
明显的二分题, 主要是怎么区间求gcd,用线段树即可
记得把数组复制一倍,防止越界
struct BIT {
int val[N << 2];
void push_up(int p) {
val[p] = __gcd(val[p << 1], val[p << 1 | 1]);
}
void build(int p, int l, int r, vector<int> &a) {
if (l == r) {
val[p] = a[l] - a[l - 1];
return;
}
int mid = l + r >> 1;
build(p << 1, l, mid, a);
build(p << 1 | 1, mid + 1, r, a);
push_up(p);
}
int ask(int p, int l, int r, int L, int R) {
if (L <= l && r <= R)
return val[p];
int mid = l + r >> 1;
if (mid >= R)
return ask(p << 1, l, mid, L, R);
if (mid < L)
return ask(p << 1 | 1, mid + 1, r, L, R);
return __gcd(ask(p << 1, l, mid, L, R), ask(p << 1 | 1, mid + 1, r, L, R));
}
} bit;
bool check(int mid, vector<int>& a) {
if (mid == 0) {
for (int n = a.size() >> 1, i = 2; i <= n; ++i)
if (a[i] ^ a[1])
return 0;
return 1;
}
int n = a.size() - 1, ls = abs(__gcd(a[1], bit.ask(1, 1, n, 2, mid + 1)));
for (int i = 2; i <= n >> 1; ++i) {
int cur = abs(__gcd(a[i], bit.ask(1, 1, n, i + 1, i + mid)));
if (cur ^ ls)
return 0;
}
return 1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int _;
for (cin >> _; _; --_) {
int n;
cin >> n;
vector<int> a((n << 1) + 1);
for (int i = 1; i <= n; ++i) {
cin >> a[i];
a[i + n] = a[i];
}
bit.build(1, 1, n << 1, a);
int l = 0, r = n - 1;
while (l < r) {
int mid = l + r >> 1;
if (check(mid, a))
r = mid;
else
l = mid + 1;
}
cout << l << '\n';
}
return 0;
}
G - How Many Paths?
有向图缩点建新图, 跑个拓扑图即可
int _, n, m, ans[N];
int c[N], scnt, cnt[N];
int dfn[N], low[N], df, st[N], top;
int deg[N];
bool inst[N], tag[N];
vector<int> h[N], nh[N];
void tarjan(int x) {
dfn[x] = low[x] = ++df;
inst[st[++top] = x] = 1;
for (auto &y : h[x])
if (!dfn[y]) {
tarjan(y);
low[x] = min(low[x], low[y]);
}
else if (inst[y])
low[x] = min(low[x], dfn[y]);
if (dfn[x] == low[x]) {
++scnt;
int z;
do {
inst[z = st[top--]] = 0;
c[z] = scnt;
++cnt[scnt];
} while (z != x);
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
for (cin >> _; _; --_) {
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
h[i].clear();
ans[i] = cnt[i] = tag[i] = c[i] = dfn[i] = 0;
}
for (int i = 1; i <= m; ++i) {
int u, v;
cin >> u >> v;
if (u ^ v)
h[u].emplace_back(v);
else
tag[u] = 1;
}
top = scnt = df = 0;
tarjan(1);
for (int i = 1; i <= scnt; ++i)
nh[i].clear();
for (int i = 1; i <= n; ++i)
if (c[i])
for (auto &y : h[i])
if (c[y] && c[i] != c[y]) {
nh[c[i]].emplace_back(c[y]);
++deg[c[y]];
}
ans[c[1]] = 1;
for (int i = 1; i <= n; ++i)
if (c[i] && tag[i])
ans[c[i]] = -1;
queue<int> q;
q.push(c[1]);
while (!q.empty()) {
int x = q.front();
q.pop();
if (cnt[x] > 1)
ans[x] = -1;
for (auto &y : nh[x]) {
if (--deg[y] == 0)
q.push(y);
if (ans[x] == -1)
ans[y] = -1;
else if (ans[y] != -1) {
ans[y] = min(2, ans[y] + 1);
if (ans[x] == 2)
ans[y] = 2;
}
}
}
for (int i = 1; i <= n; ++i)
cout << ans[c[i]] << char(" \n"[i == n]);
}
return 0;
}