求问:这种写法为什么会 TLE on #5
查看原帖
求问:这种写法为什么会 TLE on #5
556975
PNNNN楼主2024/9/26 20:05
#include<bits/stdc++.h>
#define fr first
#define sc second
using namespace std;

int n,m,q;

struct line{
    int x,y,w;
}e[1000005];

namespace Rana{
	#define ls k<<1
    #define rs k<<1|1
    vector <line> t[1000005<<2];
    int f[1605],siz[1605];
    inline void swap(int &x,int &y){
    	x^=y^=x;return;
	}
    inline int find(int x){
        return f[x]==x?x:f[x]=find(f[x]);
    }
    inline void merge(int x,int y){
        x=find(x),y=find(y);
        if(siz[x]>siz[y])swap(x,y);
        if(x!=y)f[x]=y;return;
    }
    inline void init(vector<line> &rana){
        for(line E:rana){
            f[E.x]=E.x,f[E.x+n]=E.x+n;
            f[E.y]=E.y,f[E.y+n]=E.y+n;
            siz[E.x]=siz[E.y]=siz[E.x+n]=siz[E.y+n]=1;
        }return;
    }
    inline vector<line> operator +(vector<line> A,vector<line> B){
        vector<line> res;
        init(A),init(B);
        int it1=0,it2=0,flag=0;
		while(!flag&&(it1<A.size()||it2<B.size())){
            if(it2>=B.size()||(it1<A.size()&&A[it1].w>B[it2].w)){
                int fx=find(A[it1].x),fy=find(A[it1].y);
                if(fx==find(A[it1].y+n))continue;
                merge(fx,A[it1].y+n),merge(fy,A[it1].x+n);
                res.push_back(A[it1]);
                if(find(A[it1].x)==find(A[it1].y))flag=1;
                it1++;
            }else{
                int fx=find(B[it2].x),fy=find(B[it2].y);
                if(fx==find(B[it2].y+n))continue;
                merge(fx,B[it2].y+n),merge(fy,B[it2].x+n);
                res.push_back(B[it2]);
                if(find(B[it2].x)==find(B[it2].y))flag=1;
                it2++;
            }
        }
		return res;
    }
    inline void pushup(int k){
        t[k]=t[ls]+t[rs];return;
    }
    inline void build(int k=1,int l=1,int r=m){
        if(l==r){
            t[k]={e[l]};
        }else{
            int mid=l+r>>1;
            build(ls,l,mid),build(rs,mid+1,r);
            pushup(k);
        }return;
    }
    inline vector<line> query(int L,int R,int k=1,int l=1,int r=m){
        if(L<=l&&r<=R){
            return t[k];
        }else{
            int mid=l+r>>1;
            if(R<=mid)return query(L,R,ls,l,mid);
            if(L>mid)return query(L,R,rs,mid+1,r);
            return query(L,R,ls,l,mid)+query(L,R,rs,mid+1,r);;
        }
    }
    #undef ls
    #undef rs
}

inline int read(){
	register int x(0),t(0);
	static char ch=getchar();
	while(!isdigit(ch)){t|=(ch=='-'),ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48),ch=getchar();}
	return t?-x:x;
}

signed main(){
	
    n=read(),m=read(),q=read();
    for(int i=1;i<=m;i++){
        e[i]={read(),read(),read()};
    }
    Rana::build();
    for(int i=1;i<=q;i++){
        int l=read(),r=read(),ans=-1;
        vector<line> res=Rana::query(l,r);
        Rana::init(res);
        for(line E:res){
            Rana::merge(E.x,E.y+n),Rana::merge(E.y,E.x+n);
            if(Rana::find(E.x)==Rana::find(E.y)){
                ans=E.w;break;
            }
        }
//        (ans<0?cout<<"win\n":cout<<ans<<'\n');
		cout<<ans<<'\n';
    }

    return 0;
}

rt,我觉得应该是线段树 pushup TLE了,写的是归并排序。但是会TLE,且先塞一起排序,再去掉没用的边会更快,不知道为什么。

2024/9/26 20:05
加载中...