这道题就是以前还不会的区间覆盖然后查询的问题(这道题是按顺序覆盖,还比较好做了)。
其实相对于普通的线段树,就是没有向上合并的过程而已(因为没什么用)。
查询的时候就是值域全部查询,一个一个点往下找,就可以了,根本就没有太复杂的东西。
当然这题还要离散化,跟普通离散化不大一样,对于距离大于1的点,我们还得插入一个点,否则会出现一些错误(其他博客也有说,或者就是大家想的那些)。
要注意的是,这类题在初始化的时候,线段树所有点的初始值必须都一样,否则下传的时候会发现各种奇葩错误。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<string>
#include<queue>
#include<stack>
#include<bitset>
#include<list>
#include<set>
#include<utility>
#include<iomanip>
#define IO ios::sync_with_stdio(false)
#define eps 1e-7
//#define int long long
using namespace std;
struct node
{
int l,r,sum;
}t[40005*4];
int li[40005],ri[40005],vis[40005],lis1[40005],len1,len2,n,tt,len3,ans;
void push_down(int rt)
{
if(t[rt].sum!=0)
{
t[rt*2].sum=t[rt].sum;
t[rt*2+1].sum=t[rt].sum;
t[rt].sum=0;
}
}
void build(int rt,int l,int r)
{
t[rt].l=l,t[rt].r=r;
if(l==r)
{
t[rt].sum=0;
return;
}
int mid=l+r>>1;
build(rt*2,l,mid);
build(rt*2+1,mid+1,r);
//t[rt].sum=-1;
}
void upd(int rt,int l,int r,int v)
{
if(l<=t[rt].l&&r>=t[rt].r)
{
t[rt].sum=v;
return;
}
push_down(rt);
int mid=t[rt].l+t[rt].r>>1;
if(l<=mid)
{
upd(rt*2,l,r,v);
}
if(r>mid)
{
upd(rt*2+1,l,r,v);
}
}
void ask(int rt,int l,int r)
{
if(t[rt].sum!=0)
{
if(!vis[t[rt].sum])
{
vis[t[rt].sum]=1;
//cout<<t[rt].l<<" "<<t[rt].r<<" "<<t[rt].sum<<endl;
ans++;
}
return;
}
if(l==r)return;
int mid=l+r>>1;
ask(rt*2,l,mid);
ask(rt*2+1,mid+1,r);
}
int main()
{
scanf("%d",&tt);
while(tt--)
{
memset(t,0,sizeof(t));
memset(vis,0,sizeof(vis));
ans=len3=len1=len2=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d %d",&li[i],&ri[i]);
lis1[++len1]=li[i];
lis1[++len1]=ri[i];
}
sort(lis1+1,lis1+len1+1);
len2=unique(lis1+1,lis1+len1+1)-(lis1+1);
len3=len2;
for(int i=2;i<=len2;i++)
{
if(lis1[i]-lis1[i-1]>1)
{
lis1[++len3]=lis1[i-1]+1;
}
}
sort(lis1+1,lis1+len3+1);
build(1,1,len3);
//cout<<len3<<endl;
/*for(int i=1;i<=len3;i++)
{
cout<<lis1[i]<<endl;
}*/
for(int i=1;i<=n;i++)
{
int ll=lower_bound(lis1+1,lis1+len3+1,li[i])-lis1;
int rr=lower_bound(lis1+1,lis1+len3+1,ri[i])-lis1;
//cout<<"i:"<<i<<" "<<ll<<" "<<rr<<" "<<li[i]<<" "<<ri[i]<<" "<<endl;
upd(1,ll,rr,i);
}
ask(1,1,len3);
printf("%d\n",ans);
}
}