用线段树和并查集两种方法写的,线段树的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;
}