题意
向墙上按顺序贴n张海报,第i张海报覆盖范围为[li , ri], 求最后能看到几张海报。
题解
首先肯定是线段树的区间更新,但是由于 li 和 ri 的范围是 1e7, 直接存数会爆炸,所以需要离散化。(看了很多题解,大家都是先将2*n个点排序,然后在update的时候二分找位置)本人的离散化比较奇特,是放在结构体里的。
一个需要注意的点是,两个点相差大于一的时候,要向中间插入一个点,所以建树的时候需要开4*n,具体原因,请看其他题解。:)
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int MAX_N = 50010;
typedef long long ll;
int a[MAX_N];
struct Point
{
int x;
int i;
int y;
int z;
}point[MAX_N];
struct node
{
int l;
int r;
ll lazy;
}node[MAX_N<<2];
void build(int l,int r,int rt)
{
node[rt].l=l;
node[rt].r=r;
node[rt].lazy = 0;
if(l == r)
{
return ;
}
int m= (l+r)>>1;
build(lson);
build(rson);
}
void pushdown(int rt)
{
if(node[rt].lazy == 0)
return ;
node[rt<<1].lazy = node[rt].lazy;
node[rt<<1|1].lazy = node[rt].lazy;
node[rt].lazy = 0;
}
void update(int l,int r,ll z,int rt)
{
if(l<=node[rt].l && node[rt].r<=r)
{
node[rt].lazy = z;
return ;
}
if(node[rt].l == node[rt].r)
return ;
pushdown(rt);
int m = (node[rt].l+node[rt].r)>>1;
if(l<=m)
{
update(l,r,z,rt<<1);
}
if(m<r)
{
update(l,r,z,rt<<1|1);
}
}
void query(int rt)
{
if(node[rt].lazy > 0)
{
int x = node[rt].lazy;
a[x] = 1;
return ;
}
if(node[rt].l == node[rt].r)
return ;
query(rt<<1);
query(rt<<1|1);
}
bool cmp(Point A, Point B)
{
return A.x<B.x;
}
bool cmp2(Point A,Point B)
{
if(A.i == B.i)
return A.y<B.y;
else
return A.i<B.i;
}
int main()
{
int n,q;
int T;
cin>>T;
int t = 1;
while(T--)
{
memset(a,0,sizeof(a));
cin>>n;
build(1,4*n,1);
int cnt = 1;
for(int i=1;i<=n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
point[cnt].x = a;
point[cnt].i = i;
point[cnt++].y = 1;
point[cnt].x = b;
point[cnt].i = i;
point[cnt++].y = 2;
}
sort(point+1,point+cnt,cmp);
int tmp = 1;
point[1].z = 1;
for(int i=2;i<cnt;i++)
{
if(point[i].x == point[i-1].x)
{
point[i].z = tmp;
}
else
{
if(point[i].x - point[i-1].x >1 )
tmp++;
tmp++;
point[i].z = tmp;
}
}
sort(point+1,point+cnt,cmp2);
for(int i=1;i<=2*n;i+=2)
{
update(point[i].z,point[i+1].z,i/2+1,1);
}
query(1);
int ans = 0;
for(int i=1;i<=n;i++)
{
ans += a[i];
}
printf("%d\n",ans);
}
return 0;
}