不懂就问:数组开4e7不会MLE而2e7会

P3740 [HAOI2014] 贴海报

Autumn_0930 @ 2024-07-22 19:53:40

用线段树和并查集两种方法写的,线段树的tree[]开到了4e7,而并查集v[]和f[]加起来也就是2e7,为什么线段树AC了而并查集最后两个点MLE了呢?

具体如下:

线段树

#include<bits/stdc++.h>
using namespace std;
#define ls rt<<1
#define rs rt<<1|1
const int N=1e7+1,M=1e3+1;
int flag,ans=0,a[M],b[M],tree[N*4];
void upd(int rt,int l,int r,int L,int R,int i){
    if(l==r){
        if(tree[rt]==0){
            tree[rt]++;
            flag=1;
        }
        return;
    }
    if(L<=l&&r<=R){
        if(tree[rt]==r-l+1) return;
    }
    int mid=l+r>>1;
    if(L<=mid) upd(ls,l,mid,L,R,i);
    if(R>mid) upd(rs,mid+1,r,L,R,i);
    tree[rt]=tree[ls]+tree[rs];
}
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++) scanf("%d %d",&a[i],&b[i]);
    for(int i=m;i>=1;i--){
        flag=0;
        upd(1,1,n,a[i],b[i],i);
        if(flag) ans++;
    }
    cout<<ans<<endl;
    return 0;
}

并查集

// 并查集
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+1,M=1e3+1;
int ans=0,n,m,a[M],b[M],c[N],v[M],f[N];
int getf(int x){
    if(f[x]==x) return x;
    return f[x]=getf(f[x]);
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=1;i<=m;i++) scanf("%d %d",&a[i],&b[i]);
    for(int i=m;i>=1;i--){
        for(int j=getf(b[i]);j>=a[i];j=getf(j-1)){ //找到下一个未被染色的点 
            c[j]=i;
            f[j]=j-1; //给当前点染色 
        }
    }
    for(int i=1;i<=n;i++){
        if(!v[c[i]]&&c[i]){
            v[c[i]]=1;
            ans++;
        }
    }
    printf("%d",ans);
    return 0;
}

by YuYuanPQ @ 2024-07-22 20:02:05

@Autumn_0930 你空间少了反而 MLE,可能是因为 RE。(RE 可以导致各种错误)


by YuYuanPQ @ 2024-07-22 20:03:19

@Autumn_0930 哦,找到了。

可以参考一下这个 讨论,应该是递归爆栈的问题。


by Grammar__hbw @ 2024-07-22 20:04:19

@Autumn_0930 你确定你开的M和N是对的吗qwqwq


by Autumn_0930 @ 2024-07-22 20:13:14

@YuYuanPQ

好的,谢谢dalao


by Autumn_0930 @ 2024-07-22 20:14:05

@Grammar__hbw 我不道哇 应该没什么问题吧……(我再看看


by Autumn_0930 @ 2024-08-20 22:33:31

此问已结

留帖不删


|