QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#125971 | #5425. Proposition Composition | savacska | TL | 225ms | 57328kb | C++23 | 7.3kb | 2023-07-18 06:07:20 | 2023-07-18 06:07:23 |
Judging History
answer
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define mp make_pair
#define x first
#define y second
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef tree<int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
const int INF = (int) 1e9;
struct PokrNode
{
int min, cnt;
int upd;
};
pair <int, int> edge[250005];
PokrNode tree_pokr[1000005];
int tree_sosed[1000005];
set <pair <int, int> > strong;
int svyaz[250005];
ordered_set opa[600005];
int quant = 0;
void full_pokr(int v, int lef, int rig, int val)
{
tree_pokr[v].min += val;
tree_pokr[v].upd += val;
return;
}
void push_pokr(int v, int lef, int rig)
{
int mid = (lef + rig) / 2;
full_pokr(2 * v, lef, mid, tree_pokr[v].upd);
full_pokr(2 * v + 1, mid + 1, rig, tree_pokr[v].upd);
tree_pokr[v].upd = 0;
return;
}
void build_pokr(int v, int lef, int rig)
{
if (lef == rig) {tree_pokr[v] = {INF, 1, 0}; return;}
int mid = (lef + rig) / 2;
build_pokr(2 * v, lef, mid);
build_pokr(2 * v + 1, mid + 1, rig);
tree_pokr[v] = {INF, rig - lef + 1, 0};
return;
}
void update_pokr(int v, int lef, int rig, int A, int B, int val)
{
if (lef > B || rig < A) return;
if (A <= lef && rig <= B)
{
full_pokr(v, lef, rig, val);
return;
}
push_pokr(v, lef, rig);
int mid = (lef + rig) / 2;
update_pokr(2 * v, lef, mid, A, B, val);
update_pokr(2 * v + 1, mid + 1, rig, A, B, val);
tree_pokr[v].min = tree_pokr[2 * v].min, tree_pokr[v].cnt = tree_pokr[2 * v].cnt;
if (tree_pokr[2 * v + 1].min < tree_pokr[v].min) tree_pokr[v].min = tree_pokr[2 * v + 1].min, tree_pokr[v].cnt = tree_pokr[2 * v + 1].cnt;
else if (tree_pokr[2 * v + 1].min == tree_pokr[v].min) tree_pokr[v].cnt += tree_pokr[2 * v + 1].cnt;
return;
}
void update_pokr_point(int v, int lef, int rig, int pos, int val)
{
if (lef == rig) {tree_pokr[v] = {val, 1, 0}; return;}
push_pokr(v, lef, rig);
int mid = (lef + rig) / 2;
if (pos <= mid) update_pokr_point(2 * v, lef, mid, pos, val);
else update_pokr_point(2 * v + 1, mid + 1, rig, pos, val);
tree_pokr[v].min = tree_pokr[2 * v].min, tree_pokr[v].cnt = tree_pokr[2 * v].cnt;
if (tree_pokr[2 * v + 1].min < tree_pokr[v].min) tree_pokr[v].min = tree_pokr[2 * v + 1].min, tree_pokr[v].cnt = tree_pokr[2 * v + 1].cnt;
else if (tree_pokr[2 * v + 1].min == tree_pokr[v].min) tree_pokr[v].cnt += tree_pokr[2 * v + 1].cnt;
return;
}
void build_sosed(int v, int lef, int rig)
{
if (lef == rig) {tree_sosed[v] = 0; return;}
int mid = (lef + rig) / 2;
build_sosed(2 * v, lef, mid);
build_sosed(2 * v + 1, mid + 1, rig);
tree_sosed[v] = 0;
return;
}
void dfsik_sosed(int v, int lef, int rig, int bound, int A, int B, vector <int> &spis)
{
if (tree_sosed[v] > bound) return;
if (lef > B || rig < A) return;
if (lef == rig) {spis.pb(lef); return;}
int mid = (lef + rig) / 2;
dfsik_sosed(2 * v, lef, mid, bound, A, B, spis);
dfsik_sosed(2 * v + 1, mid + 1, rig, bound, A, B, spis);
return;
}
void update_sosed(int v, int lef, int rig, int pos, int val)
{
if (lef == rig) {tree_sosed[v] = val; return;}
int mid = (lef + rig) / 2;
if (pos <= mid) update_sosed(2 * v, lef, mid, pos, val);
else update_sosed(2 * v + 1, mid + 1, rig, pos, val);
tree_sosed[v] = min(tree_sosed[2 * v], tree_sosed[2 * v + 1]);
return;
}
void cut(int start, int lef, int rig, ll &sum_sizes, int n)
{
//cout << "Cut: " << start << '\n';
//for (int x : opa[svyaz[start]]) cout << x << ' ';
//cout << "--------------\n";
int num = svyaz[start];
int sz = (int) opa[num].size();
int kol = opa[num].order_of_key(rig) - opa[num].order_of_key(lef);
if (kol == sz) return;
sum_sizes -= (ll) sz * (sz - 1) / 2;
//cout << "Cut2: " << start << '\n';
quant++;
opa[quant].clear();
sum_sizes += (ll) kol * (kol - 1) / 2;
sum_sizes += (ll) (sz - kol) * (sz - kol - 1) / 2;
auto it1 = opa[num].find(start);
auto it2 = opa[num].lower_bound(rig);
int pr = (it1 == opa[num].begin()) ? 0 : *prev(it1);
int nx = (it2 == opa[num].end()) ? n : *it2;
if (2 * kol >= sz)
{
for (auto it = opa[num].begin(); *it != start; it++)
opa[quant].insert(*it);
for (auto it = opa[num].lower_bound(rig); it != opa[num].end(); it++)
opa[quant].insert(*it);
}
else
{
auto startIt = opa[num].find(start);
auto finishIt = opa[num].lower_bound(rig);
for (auto it = startIt; it != finishIt; it++)
opa[quant].insert(*it);
}
update_sosed(1, 1, n - 1, start, 0);
if (nx != n) update_sosed(1, 1, n - 1, nx, pr);
for (int x : opa[quant])
{
svyaz[x] = quant;
opa[num].erase(x);
}
return;
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
ios_base::sync_with_stdio(0); cin.tie(0);
int test;
cin >> test;
for (int rep = 1; rep <= test; rep++)
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
cin >> edge[i].x >> edge[i].y;
if (edge[i].x > edge[i].y) swap(edge[i].x, edge[i].y);
}
if (n == 1)
{
for (int i = 1; i <= m; i++) cout << "0\n";
continue;
}
int all_edges = n - 1, bridges = n - 1;
ll sum_sizes = 0;
strong.clear();
for (int i = 1; i <= n; i++) strong.insert(mp(i, i));
quant = 0;
build_pokr(1, 1, n - 1);
build_sosed(1, 1, n - 1);
for (int i = 1; i <= m; i++)
{
int lef = edge[i].x, rig = edge[i].y;
all_edges++;
if (lef != rig)
{
auto itlef = strong.lower_bound(mp(lef + 1, 0));
itlef--;
auto itrig = strong.lower_bound(mp(rig + 1, 0));
vector <pair <int, int> > spis;
for (auto it = itlef; it != itrig; it++)
spis.pb(*it);
if ((int) spis.size() != 1)
{
quant++;
opa[quant].clear();
}
for (int i = 1; i < (int) spis.size(); i++)
{
update_pokr_point(1, 1, n - 1, spis[i - 1].y, 0);
opa[quant].insert(spis[i - 1].y);
svyaz[spis[i - 1].y] = quant;
bridges--;
}
update_pokr(1, 1, n - 1, lef, rig - 1, 1);
if ((int) spis.size() != 1)
{
int last = 0;
for (int x : opa[quant])
{
update_sosed(1, 1, n - 1, x, last);
last = x;
}
sum_sizes += (ll) opa[quant].size() * ((ll) opa[quant].size() - 1) / 2;
}
int resL = spis[0].x, resR = spis.back().y;
for (int i = 0; i < (int) spis.size(); i++) strong.erase(spis[i]);
strong.insert(mp(resL, resR));
vector <int> starts;
dfsik_sosed(1, 1, n - 1, lef - 1, lef, rig - 1, starts);
for (int start : starts) cut(start, lef, rig, sum_sizes, n);
}
ll ans = (ll) bridges * (bridges - 1) / 2 + (ll) bridges * (all_edges - bridges);
int mn = tree_pokr[1].min, cnt = tree_pokr[1].cnt;
if (mn == 1) ans += cnt;
ans += sum_sizes;
//cout << all_edges << ' ' << bridges << ' ' << mn << ' ' << cnt << ' ' << sum_sizes << '\n';
cout << ans << '\n';
}
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 22ms
memory: 57328kb
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: 108ms
memory: 55516kb
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: 225ms
memory: 56976kb
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 ...
output:
3396899100 3396816676 3396816676 3396734253 3396734253 3396734253 3396651831 3396651831 3396651831 3396651831 3396651831 3396651831 3396651831 3396569410 3396569410 3396569410 3396569410 3396569410 3396569410 3396486990 3396404571 3396404571 3396404571 3396404571 3396322153 3396239736 3396157320 339...