This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#define MN 200071
#define MB 129
using namespace std;
using pii = pair<int, int>;
using vi = vector<int>;
int n, m, q, bucket_size, R[MN];
pii E[MN];
namespace DSU {
int PS[MB][MN];
int BadTime[MB]; /// cand s-a stricat prima data
inline void init(int id) {
for(int i = 1; i <= n; ++i) PS[id][i] = -1;
}
inline int dist(int id, int u) {
int re = 0;
while(PS[id][u] > 0) ++re, u = PS[id][u];
return re;
}
inline int repr(int id ,int u) {
while(PS[id][u] > 0) u = PS[id][u];
return u;
}
stack<pii> st[MB];
inline int time(int id) {
return st[id].size();
}
void uni(int id, int u, int v) {
int pu = repr(id, u), pv = repr(id, v);
//printf(" Am primit o operatie de uni pt %d intre %d si %d cu parintii %d si %d\n", id, u, v, pu, pv);
if(pu == pv) {
if((dist(id, u) + dist(id, v) + 1) & 1) {
//printf(" Pt comp %d, la unirea intre %d si %d s-a constatat o problema(dist de %d si %d)\n", id, u, v, dist(id, u), dist(id, v));
st[id].push({-1, -1}); ///placeholder
if(!BadTime[id]) BadTime[id] = time(id);
}
return;
}
if(PS[id][pu] > PS[id][pv]) swap(pu, pv);
st[id].push({pv, PS[id][pv]});
PS[id][pu] += PS[id][pv];
PS[id][pv] = pu;
}
void rollback(int id, int tmr) {
for(int i = time(id); i > tmr; --i) {
if(st[id].top().first != -1)
PS[id][st[id].top().first] = st[id].top().second;
st[id].pop();
}
//printf("Dupa un rollback la %d de lung %d comp are BT %d\n", id, tmr, BadTime[id]);
if(BadTime[id] > time(id)) BadTime[id] = 0;
}
inline bool okay(int id) {
return !BadTime[id] || time(id) < BadTime[id];
}
}
int nr_buckets, St[MB], Dr[MB], Bkt[MN];
void add(int poz) {
//printf("Add pt %d\n", poz);
for(int i = 1; i <= nr_buckets; ++i) {
DSU::uni(i, E[poz].first, E[poz].second);
}
}
int query(int dr) {
int id = Bkt[dr], tmr0 = DSU::time(id); ///POTI OPTIMIZA PT QUERY-uri LIMITA
//printf("Query pt poz %d la bucket-ul %d\n", dr, id);
for(int i = Dr[id]; i > dr; --i) {
DSU::uni(id, E[i].first, E[i].second);
}
int re = DSU::okay(id);
DSU::rollback(id, tmr0);
return re;
}
int main() {
cin.tie(0)->sync_with_stdio(0);
cin >> n >> m >> q;
for(int i = 1; i <= m; ++i)
cin >> E[i].first >> E[i].second;
if(m > 4)
bucket_size = lround(sqrt(double(m) / log2(double(m))));
else bucket_size = m;
//printf("The bucket size is %d\n", bucket_size);
vector<tuple<int, int, int> > Queries;
for(int i = 1; i <= q; ++i) {
int l, r;
cin >> l >> r;
Queries.push_back({l, r, i});
}
int ld = 0;
while(ld != m) {
St[++nr_buckets] = ld + 1;
ld = Dr[nr_buckets] = min(m, ld + bucket_size);
for(int i = St[nr_buckets]; i <= Dr[nr_buckets]; ++i) Bkt[i] = nr_buckets;
//printf("Bucket %d intre %d si %d\n", nr_buckets, St[nr_buckets], ld);
DSU::init(nr_buckets);
for(int i = Dr[nr_buckets] + 1; i <= m; ++i) DSU::uni(nr_buckets, E[i].first, E[i].second);
}
sort(Queries.begin(), Queries.end());
int qptr = 0;
for(int i = 1; i <= m; ++i) {
while(qptr < Queries.size() && get<0>(Queries[qptr]) == i) {
R[get<2>(Queries[qptr])] = query(get<1>(Queries[qptr]));
++qptr;
}
add(i);
}
for(int i = 1; i <= q; ++i) {
cout << (!R[i] ? "YES\n" : "NO\n");
}
return 0;
}
Compilation message (stderr)
Joker.cpp: In function 'int main()':
Joker.cpp:114:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::tuple<int, int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
114 | while(qptr < Queries.size() && get<0>(Queries[qptr]) == i) {
| ~~~~~^~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |