poj2528(线段树+区间离散)

时间:2023-03-08 17:32:27

题意:那个城市里要竞选市长,然后在一块墙上可以贴海报为自己拉票,每个人可以贴连续的一块区域,后来帖的可以覆盖前面的,问到最后一共可以看到多少张海报。
思路:一看就知道是线段树,只是说要利用到离散化,也不是那么的难,当然注意,有的离散化错误也ac了......当然,在最后没必要还一个个去询问是否覆盖,直接开个标记数组,询问到一个区间只有一个覆盖值,然后进行标记就可以。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define M 100005
struct node
{
int ll,rr;
int num;
int cnt;
}tree[8*M];
int s[4*M][2],t[4*M];
int xx[4*M];
int ans=0,flag=0;
void creat(int i,int l,int r)
{
tree[i].ll=l;
tree[i].rr=r;
tree[i].cnt=0;
tree[i].num=0;
int mid=(l+r)/2;
if(l==r)
{
//tree[i].num=0;
return;
}
creat(i*2,l,mid);
creat(i*2+1,mid+1,r);
}
void updata(int i,int left,int right,int k)
{
if(tree[i].ll==left&&tree[i].rr==right)
{
tree[i].cnt=1;
tree[i].num=k;
//if(k==2)
//printf("%d %d\n",left,right);
return;
}
if(tree[i].cnt==1)
{
tree[i*2].cnt=1;
tree[i*2+1].cnt=1;
tree[i*2].num=tree[i].num;
tree[i*2+1].num=tree[i].num;
tree[i].cnt=2;
tree[i].num=0;
}
int mid=(tree[i].ll+tree[i].rr)/2;
if(mid>=right) updata(i*2,left,right,k);
else if(mid<left) updata(i*2+1,left,right,k);
else
{
updata(i*2,left,mid,k);
updata(i*2+1,mid+1,right,k);
}
if(tree[i*2].cnt==1&&tree[i*2+1].cnt==1&&tree[i*2].num==tree[i*2+1].num)
{
tree[i].cnt=1;
tree[i].num=tree[i*2].num;
} else tree[i].cnt=2;
//printf("updata\n");
}
void quest(int i)
{
//if(k==1)
//printf("%d %d %d %d %d\n",tree[i].ll,tree[i].rr,tree[i].cnt,tree[i].num,k);
if(tree[i].cnt==1)
{
xx[tree[i].num]=1;
return;
}
if(tree[i].ll==tree[i].rr)
return;
//if(flag==1)
//return;
if(tree[i].cnt==0)
return;
quest(i*2);
quest(i*2+1); // printf("quest\n");
}
int erfen(int ll,int rr,int num)
{
while(ll<=rr)
{
int mid=(ll+rr)/2;
if(t[mid]>num)
rr=mid-1;
else
ll=mid+1;
// printf("erfen\n");
}
return rr;
}
int main()
{
int text;
scanf("%d",&text);
while(text--)
{
int n;
scanf("%d",&n);
//creat(1,1,3*n);
int cnt=0;
for(int i=0;i<n;i++)
{
scanf("%d%d",&s[i][0],&s[i][1]);
t[cnt++]=s[i][0];
t[cnt++]=s[i][1];
}
sort(t,t+cnt);
int cnt1=1; for(int i=1;i<cnt;i++)
if(t[i]!=t[i-1]) t[cnt1++]=t[i]; for(int i=cnt1-1;i>0;i--)
if(t[i]!=t[i-1]+1) t[cnt1++]=t[i-1]+1;
sort(t,t+cnt1);
for(int i=cnt1;i>0;i--)
t[i]=t[i-1];
creat(1,1,cnt1+5);
for(int i=1;i<=n;i++)
{
int ll=1,rr=cnt1;
int tmp=erfen(ll,rr,s[i-1][0]);
int tmp1=erfen(ll,rr,s[i-1][1]);
//tmp;
//tmp1;
//printf("%d %d\n",tmp,tmp1);
updata(1,tmp,tmp1,i);
}
ans=0;
memset(xx,0,sizeof(xx));
quest(1);
for(int i=1;i<=n;i++)
if(xx[i]==1)
ans++;
printf("%d\n",ans);
}
return 0;
}