萌新刚学线段树分治,30pts 求调
查看原帖
萌新刚学线段树分治,30pts 求调
610557
shinzanmonoszm 妹妹楼主2023/7/9 01:04
#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<stack>
const int sz=1e5+10;
using piit=std::pair<int,int>;
std::stack<piit>s;
struct UFS{
    int fa[sz<<1],h[sz<<1];
    void clear(int n){
        std::iota(fa+1,fa+n*2+1,1);
        std::fill(h+1,h+n*2+1,1);
    }
    int find(int u){
        if(fa[u]==u)return u;
        return find(fa[u]);
    }
    void merge(int u,int v){
        int fu=find(u),fv=find(v);
        if(fu==fv)return;
        if(h[fu]>h[fv])std::swap(fu,fv);
        fa[fu]=fv,h[fv]+=(h[fu]==h[fv]);
        s.push(std::make_pair(fu,h[fu]==h[fv]));
    }
    void split(piit op){
        h[fa[op.first]]-=op.second;
        fa[op.first]=op.first;
    }
}ufs;
bool ans[sz];
int n,m,k;
struct ST{
    std::vector<piit>tree[sz<<2];
    void add(int p,int ln,int rn,int l,int r,piit val){
        if(ln>=l&&rn<=r)return tree[p].push_back(val);
        int mid=ln+rn>>1;
        if(l<=mid)add(p<<1,ln,mid,l,r,val);
        if(r>mid)add(p<<1|1,mid+1,rn,l,r,val);
    }
    void solve(int p,int ln,int rn){
        bool flag=true;
        int top=s.size();
        for(auto i:tree[p]){
            int u=i.first,v=i.second;
            if(ufs.find(u)==ufs.find(v)){
                flag=false;
                break;
            }
            ufs.merge(u+n,v),ufs.merge(u,v+n);
        }
        if(flag){
            if(ln==rn)ans[ln]=true;
            else{
                int mid=ln+rn>>1;
                solve(p<<1,ln,mid);
                solve(p<<1|1,mid+1,rn);
            }
        }
        while(s.size()>top){
            ufs.split(s.top());
            s.pop();
        }
    }
}st;
int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n,m,k;
    std::cin>>n>>m>>k;
    ufs.clear(n);
    for(int i=1;i<=m;i++){
        int u,v,l,r;
        std::cin>>u>>v>>l>>r;
        if(l!=r)st.add(1,1,k,l+1,r,std::make_pair(u,v));
    }
    st.solve(1,1,k);
    for(int i=1;i<=k;i++){
        if(ans[i])std::cout<<"Yes\n";
        else std::cout<<"No\n";
    }
    return 0;
}
2023/7/9 01:04
加载中...