实际上这个与普通的线段树相差不大,只是貌似数据太水,暴力都可以过啊
#include
#include
#include
using namespace std;
const int Max=40000001;
struct Node{
int x,y,id;
}node[10001];
int n,m,sum[Max],lazy[Max],tot[1001];
void pushdown(int o,int len){//pushdown:对于lazy标记的一个下传
if(lazy[o]){
int left=o<<1,right=left+1;
lazy[right]=lazy[left]=lazy[o];
sum[left]=lazy[o];
sum[right]=lazy[o];
lazy[o]=0;
}
}
void update(int o,int l,int r,int x,int y,int v){//一个上传操作
if(x<=l and r<=y){
sum[o]=lazy[o]=v;//sum[i]表示i这个节点当前的颜色
return;
}
pushdown(o,r-l+1);
int mid=(l+r)>>1,left=o<<1,right=left+1;
if(x<=mid)update(left,l,mid,x,y,v);
if(y>mid)update(right,mid+1,r,x,y,v);
}
void query(int o,int l,int r,int x,int y){//统计各个颜色都有多少个是外露的
if(!(l^r)){
tot[sum[o]]++;//即sum[o]这个节点的颜色的tot+1,tot[i]表示i这个颜色外露的个数
return;
}
int mid=(l+r)>>1,left=o<<1,right=left+1;
pushdown(o,r-l+1);
if(x<=mid)query(left,l,mid,x,y);
if(mid+1<=y)query(right,mid+1,r,x,y);
}
int main(){
int maxn=-1,ans=0;
scanf("%d%d",&m,&n);
for(register int i=1;i<=n;i++){
scanf("%d%d",&node[i].x,&node[i].y);
maxn=max(node[i].y,maxn);
node[i].id=i;
}
for(register int i=1;i<=n;i++){
update(1,1,maxn,node[i].x,node[i].y,node[i].id);
}
query(1,1,maxn,1,maxn);//统计答案
for(register int i=1;i<=n;i++){
if(tot[i])ans++;
}
printf("%d\n",ans);
return 0;
}