TLE on 17 求助
查看原帖
TLE on 17 求助
366639
hh弟中弟楼主2025/2/2 20:22

写的 Boruvka 算法,每次查前后缀,本地跑 1.2s,CF 上疯狂 T。

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define pii std::pair<int,int>
typedef long long ll;
typedef unsigned long long ull;
std::mt19937_64 myrand(std::chrono::high_resolution_clock::now().time_since_epoch().count());
inline ll read(){char ch=getchar();ll x=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;}
template<typename T> inline void write(T x){if(x<0)putchar('-'),x=-x;if(x>=10)write(x/10);putchar(x%10+'0');}
template<typename T> inline void Min(T&x,T y){if(x>y)x=y;}
template<typename T> inline void Max(T&x,T y){if(x<y)x=y;}
const int N=2e5+5,M=N*30,inf=INT_MAX;
int n,cnt,son[M][2],tot,id,to[M],size[M],s[N],top;
pii e[N],a[N];
ll ans;
std::vector<int> v[N];
struct DSU{
    int fa[N],size[N];
    inline void init(){for(int i=1;i<=n;++i)fa[i]=i,size[i]=1;}
    inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    inline void merge(int x,int y){x=find(x),y=find(y);if(size[x]>size[y])std::swap(x,y);size[y]+=size[x];fa[x]=y;}
}dsu;
inline void insert(int x,int bl){
    int p=0;for(int i=29;~i;--i){
        int zc=(x>>i)&1;
        if(!son[p][zc])son[p][zc]=++cnt;
        p=son[p][zc];size[p]++;
    }
    if(!to[p])to[p]=++id;v[to[p]].eb(bl);
}
inline pii query(int x){
    int p=0;pii res={0,0};for(int i=29;~i;--i){
        int zc=(x>>i)&1;
        if(size[son[p][zc]])p=son[p][zc];
        else res.fi+=1<<i,p=son[p][!zc];
    }
    if(!v[to[p]].size())res.fi=inf;else res.se=v[to[p]][0];return res;
}
inline void Boruvka(){
    for(int i=1;i<=n;++i)e[i]={inf,0};
    for(int i=1;i<=cnt;++i)size[i]=0;
    for(int i=1;i<=id;++i)v[i].clear();
    for(int i=1;i<=n;++i){
    	if(dsu.find(a[i].se)!=dsu.find(a[i-1].se)){
    		int id=dsu.find(a[i-1].se);
    		while(top)insert(s[top--],id);
    	}
    	Min(e[dsu.find(a[i].se)],query(a[i].fi));s[++top]=a[i].fi;
    }
    top=0;
    for(int i=1;i<=cnt;++i)size[i]=0;
    for(int i=1;i<=id;++i)v[i].clear();
    for(int i=n;i;--i){
    	if(dsu.find(a[i].se)!=dsu.find(a[i+1].se)){
    		int id=dsu.find(a[i+1].se);
    		while(top)insert(s[top--],id);
    	}
    	Min(e[dsu.find(a[i].se)],query(a[i].fi));s[++top]=a[i].fi;
    }
    top=0;
    for(int i=1;i<=n;++i){
        int u=dsu.find(i),v=dsu.find(e[u].se),w=e[u].fi;
        if(u==v)continue;
        ans+=w;tot++;dsu.merge(u,v);
    }
}
signed main(){
    // freopen("in.in","r",stdin);freopen("out.out","w",stdout);
    std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
    n=read();for(int i=1;i<=n;++i)a[i]={read(),0};
    std::sort(a+1,a+n+1);n=std::unique(a+1,a+n+1)-a-1;for(int i=1;i<=n;++i)a[i].se=i;
    dsu.init();
    while(tot<n-1)Boruvka();std::cout<<ans<<'\n';
}
2025/2/2 20:22
加载中...