lgP5787 二分图 /【模板】线段树分治
题意

sol.线段树分治板子 + 可撤销并查集按秩合并
#include<bits/stdc++.h>
#define MAXN 400005
using namespace std;
int n,m,k,ans[MAXN];
int fa[MAXN],sz[MAXN],dis[MAXN];
vector< pair<int , int> >vec[MAXN * 4];
int found(int x){
if(fa[x] == x){
dis[x] = 0;
return x;
}
int zz = found(fa[x]);
return zz;
}
void update(int rt , int l , int r , int x , int y , pair<int , int> v){
if(r < x || l > y)return;
if(x <= l && r <= y)return (void)(vec[rt].push_back(v));
int mid = (l + r) >> 1;
update(rt << 1 , l , mid , x , y , v);
update(rt << 1 | 1 , mid + 1 , r , x , y , v);
}
void que(int rt , int l , int r){
int mid = (l + r) >> 1;
int fx,fy,x,y;
int judge = 0;
stack< pair<int , int> >q;
while(!q.empty())q.pop();
for(int i = 0 ; i < vec[rt].size() ; i++){
x = vec[rt][i].first , y = vec[rt][i].second;
fx = found(x) , fy = found(y);
if(fx == fy && dis[x] == dis[y])judge = 1;//撤销之前的操作
else if(fx != fy){
fa[fx] = fy , dis[fx] = dis[y] ^ 1 , sz[fy] += sz[fx];
q.push(make_pair(fx , fy));
}
}
if(!judge){
if(l == r)return (void)(ans[l] = 1);
que(rt << 1 , l , mid);
que(rt << 1 | 1 , mid + 1 , r);
}
pair<int , int>now;
while(!q.empty()){
now = q.top() , q.pop();
sz[now.second] -= sz[now.first];
fa[now.first] = now.first;
}
}
int main(){
scanf("%d%d%d" , &n , &m , &k);
for(int i = 1 ; i <= n ; i++)fa[i] = i , sz[i] = 1 , dis[i] = 0;
int x,y,l,r;
while(m--){
scanf("%d%d%d%d" , &x , &y , &l , &r);
l++;
update(1 , 1 , k , l , r , make_pair(x , y));
}
que(1 , 1 , k);
for(int i = 1 ; i <= k ; i++){
if(ans[i])cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}

浙公网安备 33010602011771号