QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#204185 | #5425. Proposition Composition | UrgantTeam | TL | 637ms | 32028kb | C++23 | 6.9kb | 2023-10-07 05:09:30 | 2023-10-07 05:09:31 |
Judging History
answer
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<bits/stdc++.h>
using namespace __gnu_pbds;
using namespace std;
typedef tree <
int,
null_type,
less < int >,
rb_tree_tag,
tree_order_statistics_node_update > ordered_set;
typedef long long ll;
int const maxn = 25e4 + 5;
set < int > b[3];
int nxtL[maxn], nxtR[maxn];
int cmp[maxn];
ll sz[maxn], add;
int righ[(1 << 19)], lef[(1 << 19)], n;
ordered_set in[maxn];
inline void upd(int c, int x) {
add -= sz[c] * (sz[c] - 1) / 2;
sz[c] += x;
add += sz[c] * (sz[c] - 1) / 2;
}
void build(int i, int l, int r) {
if (r - l == 1) righ[i] = nxtR[l], lef[i] = nxtL[l];
else {
int m = (r + l) / 2;
build(2 * i + 1, l, m);
build(2 * i + 2, m, r);
righ[i] = max(righ[2 * i + 1], righ[2 * i + 2]);
lef[i] = min(lef[2 * i + 1], lef[2 * i + 2]);
}
}
void update(int i, int l, int r, int lq) {
if (r - l == 1) righ[i] = nxtR[l], lef[i] = nxtL[l];
else {
int m = (r + l) / 2;
if (lq < m) update(2 * i + 1, l, m, lq);
else update(2 * i + 2, m, r, lq);
righ[i] = max(righ[2 * i + 1], righ[2 * i + 2]);
lef[i] = min(lef[2 * i + 1], lef[2 * i + 2]);
}
}
int getR(int i, int l, int r, int lq, int rq) {
if (lq >= r || l >= rq || righ[i] < rq) return -1;
if (r - l == 1) return l;
int m = (r + l) / 2;
int res = getR(2 * i + 1, l, m, lq, rq);
if (res == -1) res = getR(2 * i + 2, m, r, lq, rq);
return res;
}
int getL(int i, int l, int r, int lq, int rq) {
if (lq >= r || l >= rq || lef[i] >= lq) return -1;
if (r - l == 1) return l;
int m = (r + l) / 2;
int res = getL(2 * i + 1, l, m, lq, rq);
if (res == -1) res = getL(2 * i + 2, m, r, lq, rq);
return res;
}
void func1(int c, int u, int v, int to) {
auto it = in[c].lower_bound(u);
vector < int > del;
int lst = -1;
if (it != in[c].begin()) {
it--;
lst = *it;
it++;
}
while (it != in[c].end()) {
int now = *it;
if (now >= v) break;
in[to].insert(now);
upd(to, 1);
upd(c, -1);
cmp[now] = to;
it++;
del.push_back(now);
}
for (auto key : del) in[c].erase(key);
nxtR[del.back()] = del.back();
nxtL[del[0]] = del[0];
update(0, 1, n, del[0]);
update(0, 1, n, del.back());
if (lst != -1) {
if (it == in[c].end()) nxtR[lst] = lst;
else nxtR[lst] = *it;
update(0, 1, n, lst);
}
if (it != in[c].end()) {
if (lst == -1) {
nxtL[*it] = *it;
} else {
nxtL[*it] = lst;
}
update(0, 1, n, *it);
}
}
void func2(int c, int u, int v, int to) {
auto it = in[c].begin();
vector < int > del;
while (it != in[c].end()) {
int now = *it;
if (now >= u) break;
in[to].insert(now);
cmp[now] = to;
upd(to, 1);
upd(c, -1);
del.push_back(now);
it++;
}
if (it != in[c].end()) {
nxtL[*it] = *it;
update(0, 1, n, *it);
}
it = in[c].lower_bound(v);
assert(it != in[c].begin());
it--;
int tmp = *it;
assert(tmp >= u);
nxtR[tmp] = tmp;
update(0, 1, n, tmp);
it++;
if (!del.empty()) {
if (it == in[c].end()) {
nxtR[del.back()] = del.back();
} else {
nxtR[del.back()] = *it;
}
update(0, 1, n, del.back());
}
if (it != in[c].end()) {
if (!del.empty()) nxtL[*it] = del.back();
else nxtL[*it] = *it;
update(0, 1, n, *it);
}
while (it != in[c].end()) {
int now = *it;
in[to].insert(now);
cmp[now] = to;
upd(to, 1);
upd(c, -1);
del.push_back(now);
it++;
}
for (auto key : del) in[c].erase(key);
}
main() {
#ifdef HOME
freopen("input.txt", "r", stdin);
#endif // HOME
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--) {
int m, u, v, cur = 2;
cin >> n >> m;
for (int j = 0; j < 3; j++) b[j] = {};
for (int i = 1; i <= n; i++) sz[i] = 0, in[i] = {};
for (int i = 1; i < n; i++) b[0].insert(i), nxtL[i] = max(1, i - 1), nxtR[i] = min(i + 1, n - 1), cmp[i] = 1, sz[1]++, in[1].insert(i);
add = sz[1] * (sz[1] - 1) / 2;
if (n > 1) build(0, 1, n);
for (int M = 1; M <= m; M++) {
cin >> u >> v;
if (u > v) swap(u, v);
for (int j = 1; j >= 0; j--) {
auto it = b[j].lower_bound(u);
vector < int > del;
while (it != b[j].end() && *it < v) {
del.push_back(*it);
it++;
}
for (auto key : del) {
b[j].erase(key);
b[j + 1].insert(key);
}
while (n > 1 && u < v) {
int pos = getR(0, 1, n, u, v);
if (pos == -1) break;
int L = in[cmp[pos]].order_of_key(u), R = in[cmp[pos]].order_of_key(v);
if (R - L <= sz[cmp[pos]] / 2) {
func1(cmp[pos], u, v, cur);
} else {
func2(cmp[pos], u, v, cur);
}
cur++;
}
while (n > 1 && u < v) {
int pos = getL(0, 1, n, u, v);
if (pos == -1) break;
int L = in[cmp[pos]].order_of_key(u), R = in[cmp[pos]].order_of_key(v);
if (R - L <= sz[cmp[pos]] / 2) {
func1(cmp[pos], u, v, cur);
} else {
func2(cmp[pos], u, v, cur);
}
cur++;
}
}
ll ans = 0, cnt = b[0].size();
ans += (ll)M * cnt;
ans += b[1].size();
ans += cnt * (n - 2);
ans -= cnt * (cnt - 1);
ans += add;
for (int i = 1; i < n; i++) {
int pos = i;
for (int j = 1; j < i; j++) {
if (cmp[i] == cmp[j]) pos = j;
}
assert(pos == nxtL[i]);
pos = i;
for (int j = i + 1; j < n; j++) {
if (cmp[i] == cmp[j]) {
pos = j;
break;
}
}
assert(pos == nxtR[i]);
int sum = 0;
for (int j = 1; j < n; j++) if (cmp[j] == cmp[i]) sum++;
assert(sum == sz[cmp[i]]);
}
cout << ans << '\n';
}
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 4ms
memory: 30864kb
input:
3 4 3 2 4 4 2 3 3 7 3 3 4 1 2 1 7 6 4 1 3 4 6 2 5 3 4
output:
6 5 6 21 24 10 15 12 3 2
result:
ok 10 numbers
Test #2:
score: 0
Accepted
time: 100ms
memory: 32028kb
input:
45540 10 9 10 1 1 10 10 1 1 10 1 10 10 1 1 10 3 3 10 1 10 4 1 2 1 10 3 4 1 10 7 6 7 1 5 6 1 7 6 6 7 1 6 7 9 7 3 3 7 7 5 4 1 1 9 1 9 1 6 5 8 7 1 8 4 4 5 6 1 1 1 8 6 6 4 5 3 3 3 2 3 1 3 3 3 9 3 1 3 3 2 2 3 3 3 1 2 2 1 1 2 3 3 1 10 1 2 1 7 1 1 7 3 8 1 3 1 3 3 3 1 3 2 2 1 3 1 3 3 3 3 6 3 1 1 3 1 3 1 3 1...
output:
45 36 36 36 36 36 36 36 36 45 36 28 21 21 15 10 10 10 6 36 44 50 57 28 21 15 28 28 21 21 15 15 10 3 1 1 3 3 3 3 1 1 1 0 0 45 21 3 1 1 1 1 1 1 1 3 1 1 1 1 1 45 36 36 36 36 36 36 36 3 3 1 0 0 0 0 0 0 3 1 0 0 15 10 10 0 0 0 0 0 0 0 0 28 34 21 6 6 6 6 1 0 0 21 15 15 0 0 0 0 0 0 0 45 53 0 0 0 0 0 0 0 0 1...
result:
ok 249586 numbers
Test #3:
score: 0
Accepted
time: 637ms
memory: 31932kb
input:
2507 86 4 41 41 36 36 31 30 86 1 110 22 1 110 110 1 11 11 110 1 110 1 110 1 1 110 107 106 72 72 106 106 74 74 1 110 110 1 58 58 110 1 110 1 1 110 101 100 110 1 100 100 110 1 8 7 114 180 114 1 114 1 114 1 1 114 1 114 114 1 37 38 49 48 105 106 1 114 90 90 1 114 9 9 114 1 67 68 20 20 114 1 1 114 54 55 ...
output:
3655 3740 3823 3570 5995 5886 5886 5886 5886 5886 5886 5778 5778 5778 5778 5778 5778 5778 5778 5778 5778 5671 5671 5671 5671 5565 6441 6328 6328 6328 6328 6328 6216 6105 5995 5995 5995 5995 5995 5995 5886 5886 5886 5886 5778 5671 5671 5565 5565 5460 5460 5460 5460 5460 5356 5253 5253 5253 5151 5151 ...
result:
ok 249877 numbers
Test #4:
score: -100
Time Limit Exceeded
input:
3 82425 27858 30801 30802 1 82425 73850 73850 1 82425 65949 65949 82425 1 76026 76025 61936 61936 82425 1 82425 1 82425 1 6504 6504 82425 1 25155 25156 79743 79743 1 82425 69406 69406 29247 29247 18351 18351 23171 23170 29704 29703 82425 1 1 82425 82425 1 74918 74917 22395 22394 893 894 82425 1 391 ...