求大佬康康是数据的锅还是我理解有问题
查看原帖
求大佬康康是数据的锅还是我理解有问题
1215295
discretely楼主2024/11/28 00:06
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;
}
2024/11/28 00:06
加载中...