链接:点击打开链接
题意:给出n张海报,问最后能看到几张海报,具体看图
代码:
#include <vector>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int siz=50005;
int n,x[siz],y[siz],vis[siz],col[siz],tree[siz<<2];
void pushdown(int rt){
if(tree[rt]){
tree[rt<<1]=tree[rt];
tree[rt<<1|1]=tree[rt];
tree[rt]=0;
}
}
void Change(int L,int R,int p,int l,int r,int rt){
if(L<=l&&r<=R){
tree[rt]=p;
return;
}
pushdown(rt);
int m=(l+r)>>1;
if(L<=m)
Change(L,R,p,l,m,rt<<1);
if(R>m)
Change(L,R,p,m+1,r,rt<<1|1);
}
void query(int l,int r,int rt){
if(l==r){
if(tree[rt])
vis[tree[rt]]=1;
return; //只查询叶子节点
}
pushdown(rt);
int m=(l+r)>>1;
query(l,m,rt<<1);
query(m+1,r,rt<<1|1);
} //其实就是一个不回溯的线段树
int comprass(int op){
int i,tmp;
sort(col,col+op);
tmp=op;
for(i=1;i<tmp;i++){
if(col[i]-col[i-1]>1)
col[op++]=(col[i]-1);
}
sort(col,col+op);
tmp=unique(col,col+op)-col;
for(i=1;i<=n;i++){
x[i]=lower_bound(col,col+tmp,x[i])-col+1;
y[i]=lower_bound(col,col+tmp,y[i])-col+1;
}
return tmp;
}
int main(){
int t,i,j,op,ans;
scanf("%d",&t);
while(t--){
memset(col,0,sizeof(col));
memset(vis,0,sizeof(vis));
memset(tree,0,sizeof(tree));
scanf("%d",&n);
op=0;
for(i=1;i<=n;i++){ //直接离散化后区间覆盖
scanf("%d%d",&x[i],&y[i]); //离散化要注意之前不相邻的元素,离散化后也
col[op++]=x[i]; //能相邻
col[op++]=y[i];
}
op=comprass(op);
for(i=1;i<=n;i++)
Change(x[i],y[i],i,1,op,1);
query(1,op,1);
ans=0;
for(i=1;i<=n;i++)
if(vis[i])
ans++;
printf("%d\n",ans);
}
return 0;
}