2143A - All Lengths Subtraction
Solution
Tutorial is loading...
...
Code
#include <iostream>
#include <cassert>
#include <vector>
#include <algorithm>
#define debug(x) #x << " = " << x << '\n'
using ll = long long;
#define YES std::cout << "YES" << std::endl;
#define NO std::cout << "NO" << std::endl;
void solve() {
int n;
std::cin >> n;
std::vector<int> p(n);
for (int i = 0; i < n; i++) {
std::cin >> p[i];
}
int l = 0, r = n - 1;
for (int i = 1; i <= n; i++) {
if (p[l] == i) {
l++;
} else if (p[r] == i) {
r--;
} else {
NO;
return;
}
}
YES;
}
int main() {
int t;
std::cin >> t;
for (int tc = 1; tc <= t; tc++) {
solve();
}
return 0;
}
Solution
Tutorial is loading...
...
Code
#include <bits/stdc++.h>
using namespace std;
int n, k, a[200005], b[200005];
void testcase()
{
cin >> n >> k;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= k; i++)
cin >> b[i];
long long ans = 0;
sort(a + 1, a + n + 1);
sort(b + 1, b + k + 1);
for (int i = 1; i <= n; i++)
ans += a[i];
long long id = n + 1;
for (int i = 1; i <= k; i++)
{
id -= b[i];
if (id >= 1)
ans -= a[id];
}
cout << ans << '\n';
}
int main()
{
int tc;
cin >> tc;
while (tc--)
testcase();
return 0;
}
Solution
Tutorial is loading...
...
Code
#include <iostream>
#include <cassert>
#include <vector>
#include <algorithm>
#include <queue>
#define debug(x) #x << " = " << x << '\n'
using ll = long long;
#define YES std::cout << "YES\n"
#define NO std::cout << "NO\n"
struct Edge {
int u, v, x, y;
};
void solve() {
int n;
std::cin >> n;
std::vector<int> deg(n, 0);
std::vector<std::vector<int>> g(n);
std::vector<std::vector<int>> gg(n);
std::vector<Edge> e(n - 1);
for (auto &[u, v, x, y] : e) {
std::cin >> u >> v >> x >> y;
u--, v--;
if (x > y) {
g[u].push_back(v);
gg[v].push_back(u);
deg[u]++;
} else {
g[v].push_back(u);
gg[u].push_back(v);
deg[v]++;
}
}
std::queue<int> q;
for (int i = 0; i < n; i++) {
if (deg[i] == 0) {
q.push(i);
}
}
std::vector<int> p(n);
for (int i = 1; i <= n; i++) {
int u = q.front();
p[u] = i;
q.pop();
for (const auto &v : gg[u]) {
deg[v]--;
if (deg[v] == 0) {
q.push(v);
}
}
}
for (auto [u, v, x, y] : e) {
if (x > y) {
assert(p[u] > p[v]);
} else if (x < y) {
assert(p[u] < p[v]);
}
}
for (int x : p) {
std::cout << x << ' ';
}
}
int main() {
#ifdef LOCAL
freopen("input.txt", "r", stdin);
#endif
std::ios_base::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t;
std::cin >> t;
for (int tc = 1; tc <= t; tc++) {
std::cerr << "Case #" << tc << ":\n";
solve();
std::cout << '\n';
}
return 0;
}
2143D1 - Inversion Graph Coloring (Easy Version)
Solution
Tutorial is loading...
Code
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 3000;
const int modulo = 1e9 + 7;
void addSelf(int &x, int y)
{
x += y;
if (x >= modulo)
x -= modulo;
}
int add(int x, int y)
{
addSelf(x, y);
return x;
}
int n, a[NMAX + 5], b[NMAX + 5];///b -> initial array, a -> equivalent permutation
int dp[2][NMAX + 1][NMAX + 1];///considering elements 1..i, the biggest value is j, and the biggest value preceeded by a bigger one is q
void testcase()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> b[i];
for (int i = 1; i <= n; i++)
{
a[i] = 1;
for (int j = 1; j < i; j++)
if (b[j] <= b[i])
a[i]++;
for (int j = i + 1; j <= n; j++)
if (b[j] < b[i])
a[i]++;
}
for (int i = 0; i < 2; i++)
for (int j = 0; j <= n; j++)
for (int q = 0; q <= n; q++)
dp[i][j][q] = 0;
dp[0][0][0] = 1;
int cr = 0;
for (int i = 1; i <= n; i++)
{
cr ^= 1;
int x = a[i];
for (int j = 0; j <= n; j++)
for (int q = 0; q <= n; q++)
dp[cr][j][q] = dp[cr ^ 1][j][q];
for (int j = 0; j <= n; j++)
{
for (int q = 0; q <= j; q++)
{
if (dp[cr ^ 1][j][q] == 0)
continue;
if (j > x and x > q)
addSelf(dp[cr][j][x], dp[cr ^ 1][j][q]);
else if (x > j)
addSelf(dp[cr][x][q], dp[cr ^ 1][j][q]);
}
}
}
int ans = 0;
for (int j = 0; j <= n; j++)
{
for (int q = 0; q <= n; q++)
addSelf(ans, dp[cr][j][q]);
}
cout << ans << '\n';///empty subsequence inclusive
}
int main()
{
int tc;
cin >> tc;
while (tc--)
testcase();
return 0;
}
2143D2 - Inversion Graph Coloring (Hard Version)
Solution
Tutorial is loading...
...
Code
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 3000;
const int modulo = 1e9 + 7;
void addSelf(int &x, int y)
{
x += y;
if (x >= modulo)
x -= modulo;
}
int add(int x, int y)
{
addSelf(x, y);
return x;
}
int n, a[NMAX + 5], b[NMAX + 5];///b -> initial array, a -> equivalent permutation
int bit_lin[NMAX + 5][NMAX + 5], bit_col[NMAX + 5][NMAX + 5];///will use an offset of one because of [0..n] range
void update_lin(int lin, int pos, int val)
{
pos++;
for (int i = pos; i <= n + 1; i += (i & -i))
addSelf(bit_lin[lin][i], val);
}
void update_col(int col, int pos, int val)
{
pos++;
for (int i = pos; i <= n + 1; i += (i & -i))
addSelf(bit_col[col][i], val);
}
int query_lin(int lin, int pos)
{
pos++;
int rr = 0;
for (int i = pos; i > 0; i -= (i & -i))
addSelf(rr, bit_lin[lin][i]);
return rr;
}
int query_col(int col, int pos)
{
pos++;
int rr = 0;
for (int i = pos; i > 0; i -= (i & -i))
addSelf(rr, bit_col[col][i]);
return rr;
}
void testcase()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> b[i];
for (int i = 1; i <= n; i++)
{
a[i] = 1;
for (int j = 1; j < i; j++)
if (b[j] <= b[i])
a[i]++;
for (int j = i + 1; j <= n; j++)
if (b[j] < b[i])
a[i]++;
}
for (int i = 0; i <= n + 1; i++)
for (int j = 0; j <= n + 1; j++)
bit_lin[i][j] = bit_col[i][j] = 0;
update_lin(0, 0, 1);
update_col(0, 0, 1);
for (int i = 1; i <= n; i++)
{
vector<pair<int, pair<int, int>>> buffs;///where to update at the end
int x = a[i];
for (int j = x + 1; j <= n; j++)
{
int lin, col, buff;
lin = j;
col = x;
buff = query_lin(j, x - 1);
buffs.push_back({buff, {lin, col}});
}
for (int q = 0; q < x; q++)
{
int lin, col, buff;
lin = x;
col = q;
buff = query_col(q, x - 1);
buffs.push_back({buff, {lin, col}});
}
for (auto it : buffs)
{
update_lin(it.second.first, it.second.second, it.first);
update_col(it.second.second, it.second.first, it.first);
}
}
int ans = 0;
for (int lin = 0; lin <= n; lin++)
addSelf(ans, query_lin(lin, n));
cout << ans << '\n';
}
int main()
{
int tc;
cin >> tc;
while (tc--)
testcase();
return 0;
}
Solution
Tutorial is loading...
Code
#include <iostream>
#include <cassert>
#include <vector>
#include <algorithm>
#define debug(x) #x << " = " << x << '\n'
using ll = long long;
#define YES std::cout << "YES\n"
#define NO std::cout << "NO\n"
void solve() {
int n;
std::cin >> n;
std::string s;
std::cin >> s;
if (s == "))))))))") {
std::cout << "(()(()))";
return;
}
if (n % 2 == 1) {
std::cout << -1;
return;
}
int delta = 0;
assert((int) s.size() == n);
for (int i = 0; i < (int) s.size(); i++) {
int value = (s[i] == '('? +1 : -1);
if (i & 1) {
value *= -1;
}
delta += value;
}
if (delta == -n || std::abs(delta) % 4 != n % 4) {
std::cout << -1;
return;
}
int plus = (n + delta) / 2;
int minus = (n - delta) / 2;
assert(minus % 2 == 0);
std::cout << "(";
for (int i = 0; i < minus / 2; i++) {
std::cout << "()";
}
std::cout << ")";
for (int i = 0; i < (plus - 2) / 2; i++) {
std::cout << "()";
}
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(0);
int t;
std::cin >> t;
for (int tc = 1; tc <= t; tc++) {
std::cerr << "Case #" << tc << ":\n";
solve();
std::cout << '\n';
}
return 0;
}
Solution
Tutorial is loading...
...
Code
#include <iostream>
#include <cassert>
#include <vector>
#include <algorithm>
#define debug(x) #x << " = " << x << '\n'
using ll = long long;
#define YES std::cout << "YES\n"
#define NO std::cout << "NO\n"
const int B = 21;
struct XorBasis {
std::vector<int> basis;
std::vector<int> who;
int sz;
void reset() {
basis.assign(B, 0);
who.clear();
sz = 0;
}
bool add(int x, int index) {
for (int i = B - 1; i >= 0; i--) {
if (x >> i & 1) {
if (!basis[i]) {
basis[i] = x;
who.push_back(index);
sz++;
return true;
}
x ^= basis[i];
}
}
return false;
}
int kth(int k) { // al k-lea cel mai mic subset xor
if (k < 1 || k > (1 << sz)) {
return -1;
}
int x = 0;
int cnt = (1 << sz);
for (int i = B - 1; i >= 0; i--) {
if (basis[i]) {
if (k > cnt / 2) {
if (!(x >> i & 1)) {
x ^= basis[i];
}
// il fac sa fie 1
k -= cnt / 2;
} else {
// il fac sa fie 0
if (x >> i & 1) {
x ^= basis[i];
}
}
cnt /= 2;
}
}
return x;
}
int count_le(int x) { // cate subset uri au xor < x?
if (x < 0) {
return 0;
}
int ret = 0;
int cnt = (1 << sz);
int mask = 0;
for (int i = B - 1; i >= 0; i--) {
if (basis[i]) {
if (x >> i & 1) {
ret += cnt / 2;
if (!(mask >> i & 1)) {
mask ^= basis[i];
}
} else {
if (mask >> i & 1) {
mask ^= basis[i];
}
}
cnt /= 2;
} else {
if ((x ^ mask) >> i & 1) {
if (x >> i & 1) {
return ret + cnt;
} else {
return ret;
}
}
}
}
return ret;
}
int count_leq(int x) { // <= x
return count_le(x + 1);
}
int jumpK(int value, int k) {
int p = count_leq(value);
return kth(p + k);
}
};
int main() {
#ifdef LOCAL
freopen("input.txt", "r", stdin);
#endif
std::ios_base::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int tc;
std::cin >> tc;
while (tc--) {
int n, q;
std::cin >> n >> q;
std::vector<int> a(n);
for (int &x : a) {
std::cin >> x;
}
XorBasis B;
B.reset();
std::vector<int> maxR(n);
for (int l = n - 1; l >= 0; l--) {
if (!B.add(a[l], l)) {
std::vector<int> ids = B.who;
ids.push_back(l);
std::sort(ids.begin(), ids.end());
B.reset();
for (int index : ids) {
B.add(a[index], index);
}
}
std::sort(B.who.begin(), B.who.end());
XorBasis aux;
aux.reset();
std::swap(B, aux);
int r = n - 1;
int maxExtend = l;
int prevIndex = l - 1;
int prevValue = -1;
for (int index : aux.who) {
if (index - 1 > maxExtend) {
r = std::min(r, maxExtend);
break;
}
int before = (prevValue == -1? -1 : B.jumpK(prevValue, index - 1 - prevIndex));
B.add(a[index], index);
int me = B.jumpK(before, 1);
if (me == -1) {
r = std::min(r, index - 1);
break;
}
maxExtend = index + (1 << B.sz) - B.count_leq(me);
prevValue = me;
prevIndex = index;
}
r = std::min(r, maxExtend);
std::swap(aux, B);
maxR[l] = r;
}
while (q--) {
int l, r;
std::cin >> l >> r;
l--, r--;
if (r <= maxR[l]) {
YES;
} else {
NO;
}
}
}
return 0;
}



