区间覆盖怎么能不用线段树数呢(线段树又短又好写).
可以发现每次覆盖的是一个区间,但是这个区间很大所以需要离散化.
如果直接离散化会出现一些很奇怪的情况:
如这样一个图,在普通的离散化后会变成:
红色的海报本来是可以看见的但是在离散化就看不见了,所以,在离散化时,如果两个相邻的值的差不是1(即中间有缝隙),需要在中间空一个位置出来.
下面放上完整的代码:
#include<bits/stdc++.h>
#define rap(i,first,last) for(int i=first;i<=last;++i)
#define Lson now*2
#define Rson now*2+1
#define Middle (left+right)/2
#define Left Lson,left,Middle
#define Right Rson,Middle+1,right
#define Now nowleft,nowright
using namespace std;
const int maxN=1e6+7;
int N,M;
int tree[maxN*4];
int lazy[maxN*4];
void PushUp(int now)//合并
{
tree[now]=tree[Lson]+tree[Rson];
}
void Down(int now,int left,int right,int _lazy)//推懒标记
{
lazy[now]=_lazy;
tree[now]=(right-left+1)*_lazy;
}
void PushDown(int now,int left,int right)//向下推懒标记
{
if(lazy[now])//如果有覆盖
{
Down(Left,lazy[now]);//向左子树推懒标记
Down(Right,lazy[now]);//向右子树推懒标记
lazy[now]=0;//懒标记清空
}
}
void UpData(int nowleft,int nowright,int cover,int now=1,int left=1,int right=N)//区间覆盖
{
if(left>nowright||nowleft>right)return;//不在范围内退出
if(nowleft<=left&&right<=nowright)//可以直接修改
{
tree[now]=(right-left+1)*cover;
lazy[now]=cover;
return;
}
PushDown(now,left,right);//推懒标记
UpData(Now,cover,Left);//修改左子树
UpData(Now,cover,Right);//修改右子树
PushUp(now);//合并
}
int Query(int who,int now=1,int left=1,int right=N)//单点查询
{
if(who<left||who>right)return 0;//不在范围内
if(left==right)//已经是叶节点了可以直接返回
{
return tree[now];
}
PushDown(now,left,right);//推懒标记
int result=Query(who,Left);//从左右子树处获得答案
result+=Query(who,Right);
PushUp(now);//合并
return result;//返回答案
}
map<int,int>Hash;//离散化
int arr[maxN*2];
int L[maxN],R[maxN];
int check[maxN];
int main()
{
scanf("%d%d",&N,&M);
rap(i,1,M)
{
scanf("%d%d",&L[i],&R[i]);
arr[i*2-1]=L[i];
arr[i*2]=R[i];
}
sort(arr+1,arr+M*2+1);//离散化部分
arr[0]=-1;
int N=0;
rap(i,1,M*2)
{
if(arr[i]!=arr[i-1])
{
if(arr[i-1]+1!=arr[i])//上方讲的注意点
N+=2;
else
N++;
Hash[arr[i]]=N;
}
}
rap(i,1,M)
{
UpData(Hash[L[i]],Hash[R[i]],i);//修改
}
int now,answer=0;
check[0]=1;
rap(i,1,N)//每个点查询,看有几种海报,用bool型数组记录
{
now=Query(i);//查询出这个位置的值
if(!check[now])//如果没有过则answer+1
{
check[now]=1;
answer++;
}
}
printf("%d",answer);//输出answer
return 0;
}