题目链接:https://vjudge.net/problem/POJ-2528
使用线段树区间更新覆盖,最后查询有多少不同的海报
需要先离散化数据,否则会超内存
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
using namespace std;
const int maxn=4*1e4+10;
const int N=1e4+10;
struct node
{
int l,r;
int val;
int mid()
{
return (l+r)>>1;
}
}Tree[maxn<<2];
int cnt,vis[N];
int l[N],r[N];
int a[maxn];
void pushdown(int rt,int m)
{
if(Tree[rt].val==-1) return;
Tree[rt<<1].val=m;
Tree[rt<<1|1].val=m;
Tree[rt].val=-1;
}
void init_tree(int rt,int l,int r)
{
Tree[rt].val=-1;
Tree[rt].l=l;
Tree[rt].r=r;
if(l==r) return;
init_tree(rt<<1,l,(l+r)>>1);
init_tree(rt<<1|1,((l+r)>>1)+1,r);
}
void update_tree(int rt,int l,int r,int c)
{
if(Tree[rt].l>=l&&Tree[rt].r<=r)
{
Tree[rt].val=c;
return;
}
pushdown(rt,Tree[rt].val);
int m = Tree[rt].mid();
if(r>m)
update_tree(rt<<1|1, l, r, c);
if(l<=m)
update_tree(rt<<1, l, r, c);
}
void query_tree(int rt,int l,int r)
{
int m = Tree[rt].mid();
if(Tree[rt].val!=-1)
{
if(!vis[Tree[rt].val])
cnt++;
vis[Tree[rt].val]=1;
return;
}
if(l==r) return;
query_tree(rt<<1, l, m);
query_tree(rt<<1|1, m+1, r);
}
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int m=0;
for(int i=0;i<n;i++)
{
scanf("%d%d",&l[i],&r[i]);
a[m++]=l[i];
a[m++]=r[i];
}
sort(a,a+m);
int t=1;
for(int i=1;i<m;i++) if(a[i]!=a[i-1]) a[t++]=a[i];
for(int i=t-1;i>=0;i--) if(a[i]!=a[i-1]+1) a[t++]=a[i-1]+1;
sort(a,a+t);
init_tree(1,1,t);
for(int i=0;i<n;i++)
{
int u=lower_bound(a,a+t,l[i])-a;
int v=lower_bound(a,a+t,r[i])-a;
update_tree(1,u+1,v+1,i+1);
}
cnt=0;
memset(vis,0,sizeof(vis));
query_tree(1,1,m);
printf("%d\n",cnt);
}
return 0;
}