이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#include <linux/limits.h>
using namespace std;
struct Query {
int id;
int l,r;
Query(){};
const bool operator<(Query& other) const
{
//if (l/512 != other.l/512) return l > other.l;
return r < other.r;
}
};
vector<pair<int,int>> edge;
struct UnionFind
{
vector<int> parent;
vector<int> size;
vector<bool> parity;
vector<pair<int,int>> history;
vector<bool> history_valid;
UnionFind(int N)
{
parent.assign(N+1,-1);
size.assign(N+1,1);
parity.assign(N+1,0);
history.assign(1,{-1,-1});
history_valid.assign(1,1);
}
pair<int,bool> find(int a,bool c = false)
{
if (parent[a]==-1) return {a,c};
return find(parent[a],c^parity[a]);
}
void unite(int a, int b)
{
auto av = find(a);
auto bv = find(b);
a = av.first;
b = bv.first;
bool apar = av.second;
bool bpar = av.second;
if(a==b)
{
history.push_back({-1,-1});
history_valid.push_back(history_valid.back()&&(apar!=bpar));
return;
}
if (size[a] < size[b]) {swap(a,b);swap(apar,bpar);}
// a > b
size[a] += size[b];
parent[b] = a;
parity[b] = apar == bpar;
history.push_back({a,b});
history_valid.push_back(history_valid.back());
}
bool isValid()
{
return history_valid.back();
}
void undo()
{
auto ab = history.back();history.pop_back();
history_valid.pop_back();
if(ab.first == -1) return;
auto a = ab.first;
auto b = ab.second;
size[a] -= size[b];
parent[b] = -1;
parity[b] = 0;
}
inline void addEdge(int i)
{
unite(edge[i-1].first,edge[i-1].second);
}
};
int id,l,r,Redge,Lpos,Rpos;
signed main()
{
int N,M,Q;
cin >> N >> M >> Q;
UnionFind unionfind(N);
edge.resize(M);
for(auto&& i : edge) cin >> i.first >> i.second;
vector<Query> query(Q);
for(auto&& i : query) cin >> i.l>> i.r;
for(int i = 0; i < Q; i++) query[i].id = i;
sort(query.begin(),query.end());
vector<bool> queryres(Q);
//Redge = N;
Lpos = 1;
Rpos = M;
Redge = M;
while(query.size())
{
auto v = query.back();query.pop_back();
id = v.id;
l = v.l;
r = v.r;
/* if (l >= Rpos)
{
for(int i = N; i > Redge; i--) unionfind.undo();
for(int i = Lpos; i < Rpos; i++) unionfind.addEdge(i);
Redge = N;
Lpos = Rpos;
Rpos = min(N,Lpos+512);
} */
for(;Redge > r; Redge--) unionfind.addEdge(Redge);
for(int i = Lpos; i < l;i++) unionfind.addEdge(i);
queryres[id] = unionfind.isValid();
for(int i = Lpos; i < l;i++) unionfind.undo();
}
for(auto i : queryres) cout << (i ? "NO\n" : "YES\n");
return 0;
}
# | 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... |