题意:在墙上贴海报 然后后一次贴上去的会覆盖上一次贴的 然后最后贴完之后求最后能够看见的有几张
解法:这一题很早就想写了 但是当我写了大量线段树反倒是觉得这个真的有什么优化也只是再插入的时候了 然后最后统计区间居然接近遍历了整棵树 这个使我困惑了很久 悲剧的是 这题并不需要pushup 这是真的 因为我们也没有什么办法统计出这个区间中的不同的颜色的个数和信息的 毕竟这可是有1w种颜色啊
#include<cstdio>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 111111
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((l+r)>>1)
int set[maxn<<2],ha[maxn],_l[maxn],_r[maxn];
int ans;
inline void down(int rt){
if(set[rt]!=-1){
set[ls]=set[rs]=set[rt];
set[rt]=-1;
}
}
inline void ins(int rt,int l,int r,int L,int R,int w){
if(L<=l&&r<=R){
set[rt]=w;return ;
}down(rt);
if(L<=mid)ins(ls,l,mid,L,R,w);
if(mid<R)ins(rs,mid+1,r,L,R,w);
}
inline void query(int rt,int l,int r){
if(set[rt]!=-1){
if(!ha[set[rt]])ans++;
ha[set[rt]]++;
return ;
}
if(l==r)return ;
query(ls,l,mid);
query(rs,mid+1,r);
}
int _,x[maxn],n,cnt,all,fi[maxn];
int main(){
scanf("%d",&_);
while(_--){
scanf("%d",&n);all=cnt=0;
for(int i=0;i<n;++i){
scanf("%d%d",&_l[i],&_r[i]);
x[cnt++]=_l[i];x[cnt++]=_r[i];
}
sort(x,x+cnt);
fi[++all]=x[0];
for(int i=1;i<cnt;++i){
// printf("%d %d\n",fi[all],x[i]);
if(fi[all]!=x[i]){
if(x[i]-fi[all]>1){
fi[++all]=x[i]-1;
}
fi[++all]=x[i];
}
}
memset(ha,0,sizeof ha);
memset(set,-1,sizeof set);
for(int i=0;i<n;++i){
int ll=(int)(lower_bound(fi+1,fi+1+all,_l[i])-fi);
int rr=(int)(lower_bound(fi+1,fi+1+all,_r[i])-fi);
ins(1,1,all,ll,rr,i+1);
}ans=0;
query(1,1,all);
printf("%d\n",ans);
}
return 0;
}