点击打开链接
题意:将海报一张一张的贴在墙上,问最后在最上面还可以看见的海报的数量
思路:将所有海报覆盖的位置进行离散化,然后二分找到每个区间覆盖的对应的离散化后的位置,然后更新节点值为当前海报的出现位置,最后统计整个大区间的节点的不同值的数量。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; const int maxn=200010; int num[maxn],L[maxn],R[maxn],t[maxn],num1[maxn],v[maxn],ans; void pushdown(int node){//区间更新之懒惰标记 if(num1[node]){ num1[node<<1]=num1[node]; num1[node<<1|1]=num1[node]; num[node<<1]=num1[node]; num[node<<1|1]=num1[node]; num1[node]=0; } } void update(int l,int r,int add,int le,int ri,int node){ if(l<=le&&ri<=r){ num1[node]=add; num[node]=add; return ; } pushdown(node); int t=(le+ri)>>1; if(l<=t) update(l,r,add,le,t,node<<1); if(r>t) update(l,r,add,t+1,ri,node<<1|1); num[node]=num[node<<1]+num[node<<1|1]; } void query(int le,int ri,int node){ if(le==ri){ if(v[num[node]]==0){ ans++; v[num[node]]=1; } return ; } pushdown(node); int t=(le+ri)>>1; query(le,t,node<<1); query(t+1,ri,node<<1|1); } int main(){ int T,n; scanf("%d",&T); while(T--){ scanf("%d",&n); memset(num,0,sizeof(num)); memset(v,0,sizeof(v));v[0]=1; int k=0; for(int i=0;i<n;i++){ scanf("%d%d",&L[i],&R[i]); t[k++]=L[i];t[k++]=R[i]; } sort(t,t+k); int len=unique(t,t+k)-t;//离散化 for(int i=0;i<n;i++){ int l=lower_bound(t,t+len,L[i])-t+1; int r=lower_bound(t,t+len,R[i])-t+1; update(l,r,i+1,1,len,1); } ans=0; query(1,len,1); printf("%d\n",ans); } return 0; }