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
此问已结
留帖不删