(2019徐州网络赛) B. so easy (线段树 || 并查集)

传送门

题意:就是两种操作,1:使得x点无效,2:查找大于等于x的最小有效点

解:由于数据达到1e9不好set,所以就线段树操作就像了,节点维护区间,和存在的有效点数,然后查询的时候,用存在的有效点数剪枝一下即可。(好像有暴力过的???

#include
#define il inline
#define pb push_back
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define SZ(a) int((a).size())
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int N=1e6+5;
//il int Add(ll &x,ll y) {return x=x+y>=mod?x+y-mod:x+y;}
//il int Mul(ll &x,ll y) {return x=x*y>=mod?x*y%mod:x*y;}
int n,m;
ll b[N];
struct node{
	int op,x;
}qu[N];
struct T{
	int l,r;
	ll sum;
}s[N<<2];
il void pushup(int rt){
	s[rt].sum=s[rt<<1].sum+s[rt<<1|1].sum;
}
il void build(int l,int r,int rt){
	if(l==r){ //左闭右开 
		s[rt].l=b[l],s[rt].r=b[l+1];
		s[rt].sum=s[rt].r-s[rt].l;
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,rt<<1);
	build(mid+1,r,rt<<1|1);
	s[rt].l=s[rt<<1].l,s[rt].r=s[rt<<1|1].r;
	pushup(rt);
}
il void update(int l,int r,int rt,int X){
	if(l==r){
		s[rt].sum--;
		return ;
	}
	int mid=(l+r)>>1;
	if(X>1;
	if(Xn) continue;
		b[++cnt]=qu[i].x;
	}
	b[++cnt]=n+5;
	sort(b+1,b+cnt+1);
	int sz=unique(b+1,b+cnt+1)-(b+1); 
	build(1,sz-1,1);	
	for(int i=1;i<=m;++i){
		if(qu[i].op==2){
			if(qu[i].x>n) printf("-1\n");
			res=0;
			query(1,sz-1,1,qu[i].x);
			if(res!=0) printf("%lld\n",res);
			else printf("-1\n");
		}
		else{
			if(qu[i].x>n) continue;
			update(1,sz-1,1,qu[i].x);
		}
	}
	return 0;
}








题解用map模拟并查集简单好写,菜啊;

#include
#define il inline
#define pb push_back
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define SZ(a) int((a).size())
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int N=1e6+5;
//il int Add(ll &x,ll y) {return x=x+y>=mod?x+y-mod:x+y;}
//il int Mul(ll &x,ll y) {return x=x*y>=mod?x*y%mod:x*y;}
int n,m;
unordered_map fa;
il int find(int x){
	if(!fa.count(x)) return x;
	return fa[x]=find(fa[x]);
} 
int main(){
	std::ios::sync_with_stdio(0);cin.tie(0);
	scanf("%d%d",&n,&m);
	int op,x;
	for(int i=1;i<=m;++i){
		scanf("%d%d",&op,&x);
		if(op==1)	fa[x]=find(x+1);
		else{
			int ans=find(x);
			printf("%d\n",(ans>n?-1:ans));
		}
	}
	return 0;
}

 

你可能感兴趣的:(线段树,并查集)