离散化 Hihocoder-1079 线段树+离散化

题目链接:Hihocoder-1079

主要思路:

由于本题数值范围较大,又只用比较大小关系即可,故用离散化来离散左端点和右端点即可.又因为这道题是连续性线段树,故我们只用将编号便给每条线段.故点1到点2这条线段编为1,点2到点3这条线段编为2,以此类推.故每个点区间[L,R]为线段区间[L,R-1].

用线段树存下区间内海报的状态(如有一张海报则存该海报的编号,若多张或是没有则存-1).最后枚举每一条线段即可.

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define M 100005
using namespace std;
int L[M],R[M],C[M<<1],id=0;
struct node {
	int L,R,d,add;
	node() {
		d=-1;
		add=0;
	}
	void Add(int t){
		add=t;
		d=t;
		return;
	}
};
struct Segment {
	node tree[M<<2];//四倍数组注意 
	int tot;
	bool mark[M];//存这个海报被枚举过了没 
	Segment(){
		memset(mark,0,sizeof(mark));//初始化 
		tot=0;
	}
	void Down(int p){
		int &t=tree[p].add;
		if(t==0)return;
		tree[p<<1].Add(t);
		tree[p<<1|1].Add(t);
		t=0;
		return;
	}
	void Build(int L,int R,int p) {
		tree[p].d=tree[p].add=0;
		tree[p].L=L,tree[p].R=R;
		if(L==R) {
			return;
		}
		int mid=L+R>>1;
		Build(L,mid,p<<1);
		Build(mid+1,R,p<<1|1);
	}
	void turn(int L,int R,int d,int p) {
		if(tree[p].L==L&&tree[p].R==R) {
			tree[p].d=d;
			tree[p].add=d;
			return;
		}
		Down(p);//每次遍历到这个节点时更新他的子节点.(即为延时更新) 
		int mid=tree[p].L+tree[p].R>>1;
		if(R<=mid){
			turn(L,R,d,p<<1); 
		}else if(L>mid)turn(L,R,d,p<<1|1);
		else {
			turn(L,mid,d,p<<1);
			turn(mid+1,R,d,p<<1|1);
		}
	}
	void Query(int p) {
		int L=tree[p].L,R=tree[p].R;
		if(L==R) {
			int ans=tree[p].d;
			if(ans<=0)return;//如果没有被覆盖到 
			if(mark[ans])return;
			mark[ans]=1;
			tot++;
			return;
		}
		Down(p);
		int mid=L+R>>1;
		Query(p<<1);//枚举左边那一段 
		Query(p<<1|1);//枚举右边那一段 
	}
}S;
int main() {
	int n,l;
	scanf("%d%d",&n,&l);
	for(int i=1; i<=n; i++) {
		scanf("%d%d",&L[i],&R[i]);
		C[++id]=L[i];
		C[++id]=R[i];
	}
	sort(C+1,C+n+n+1);
	id=unique(C+1,C+n+n+1)-C-1;//去重 
	S.Build(1,id-1,1);
	for(int i=1; i<=n; i++) {
		L[i]=lower_bound(C+1,C+id+1,L[i])-C;//离散化 
		R[i]=lower_bound(C+1,C+id+1,R[i])-C;
		//printf("%d %d\n",L[i],R[i]-1);
		S.turn(L[i],R[i]-1,i,1);//注意是R[i]-1(此处为线段编号,而不是点的编号) 
	}
	S.Query(1);
	printf("%d\n",S.tot);
}

如果线段树不懂可以看一下我的线段树模板.

猜你喜欢

转载自blog.csdn.net/qq_35320178/article/details/81128813