L - Mayor's posters POJ - 2528

本文介绍了一种结合线段树与离散化的数据处理方法,通过具体实例展示了如何进行离散化处理,以及如何利用线段树进行区间查询,适用于解决涉及大量整数范围操作的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线段树+离散化处理

这里讲一下离散化处理

int cnt=1,i;//输入数据
		for(i=0;i<2*n;i+=2)
		{
			scanf("%d%d",&post[i].x,&post[i+1].x);
			post[i].id=cnt;
			post[i+1].id=cnt;
			cnt++;		
		}

然后

		sort(post,post+2*n,cmp);
		int pre=0,tot=0;
		for(i=0;i<2*n;i++)//离散化 
		{
			if(post[i].x==pre)
			{
				post[i].x=tot;
			}
			else
			{
				pre=post[i].x;
				post[i].x=++tot;
			}
		}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
const int maxn=100000+100;
struct node
{
	int l,r,val;
}tree[maxn*4];
int flag=0;
struct ID
{
	int id,x;
}post[maxn*4];
int cmp(ID aa,ID bb)
{
	return aa.x<bb.x;
}
int cmmp(ID aa,ID bb)
{
	if(aa.id==bb.id)
		return aa.x<bb.x;
	return aa.id>bb.id;
}
void pushup(int rt)
{
	tree[rt].val=tree[rt<<1].val&&tree[rt<<1|1].val;
}
void build(int rt,int l,int r)
{
	tree[rt].l=l;
	tree[rt].r=r;
	tree[rt].val=0;
	if(l==r)
	{
		return ;
	}
	int mid=(l+r)/2;
	build(lson);
	build(rson);
	pushup(rt);
}
void query(int rt,int l,int r)
{
	if(tree[rt].val)
		return;
	if(tree[rt].l==l&&tree[rt].r==r)
	{
		flag=1;
		tree[rt].val=1;
		return;
	}
	int mid=(tree[rt].l+tree[rt].r)/2;
	if(l>mid)
	{
		query(rt<<1|1,l,r);
	}
	else if(r<=mid)
	{
		query(rt<<1,l,r);
	}
	else
	{
		query(lson);
		query(rson);
	}
	pushup(rt);
}
int main ()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		int cnt=1,i;
		for(i=0;i<2*n;i+=2)
		{
			scanf("%d%d",&post[i].x,&post[i+1].x);
			post[i].id=cnt;
			post[i+1].id=cnt;
			cnt++;		
		}
		sort(post,post+2*n,cmp);
		int pre=0,tot=0;
		for(i=0;i<2*n;i++)//离散化 
		{
			if(post[i].x==pre)
			{
				post[i].x=tot;
			}
			else
			{
				pre=post[i].x;
				post[i].x=++tot;
			}
		}
		sort(post,post+2*n,cmmp);
		build(1,1,tot);
		int ans=0;
		for(i=0;i<2*n;i+=2)
		{
			int ll,rr;
			ll=post[i].x;
			rr=post[i+1].x;
			flag=0;
			query(1,ll,rr);
			if(flag)
				ans++;
		}
		printf("%d\n",ans); 
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值