while(top>now){
node t=nodes[top];
fa[t.x]=t.x;
high[t.y]-=t.val;
top--;
}
这里,我写成
high[t.y]-=t.val;和high[t.x]-=t.val;
都是对的,有点不理解,回退应该是回退的high[y]呀
完整代码如下
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define lc u<<1
#define rc u<<1|1
#define mid ((l+r)>>1)
const int N=2e5+10;
int n,m,k;
#define pii pair<int,int>
vector<pii> e[N*2];
struct node{
int x,y,val;
}nodes[N];
int fa[N];
int top;
int high[N];
void update(int u,int l,int r,int x,int y,pii k){
if(x<=l&&r<=y){
e[u].push_back({k});
return;
}
if(x<=mid) update(lc,l,mid,x,y,k);
if(y>mid) update(rc,mid+1,r,x,y,k);
}
int find(int u){
while(u!=fa[u]) u=fa[u];
return fa[u];
}
void merge(int u,int v){//要启发式合并(按秩合并)
int x=find(u),y=find(v);
if(high[x]>high[y]) swap(x,y);
nodes[++top]={x,y,high[x]==high[y]};
fa[x]=y;
if(high[x]==high[y]) high[y]++;
}
void solve(int u,int l,int r){
int flag=1;//1是二分图
int now=top;
for(auto t:e[u]){
if(find(t.first)==find(t.second)){
for(int i=l;i<=r;++i){
cout<<"No"<<endl;
}
flag=0;
break;
}
merge(t.first,t.second+n);
merge(t.first+n,t.second);
}
if(flag){
if(l==r) cout<<"Yes"<<endl;
else{
solve(lc,l,mid);
solve(rc,mid+1,r);
}
}
while(top>now){
node t=nodes[top];
fa[t.x]=t.x;
high[t.y]-=t.val;
top--;
}
}
int main(){
cin>>n>>m>>k;
for(int i=1;i<=2*n;++i) fa[i]=i;
for(int i=1;i<=m;++i){
int x,y,l,r;cin>>x>>y>>l>>r;
update(1,1,k,l+1,r,{x,y});
}
solve(1,1,k);
return 0;
}