离散化加线段树
学习了离散化的方法
对不同颜色的记录
一开始查询不知道什么时候返回,甚至还判断lazy=-1写麻烦了
其实只需要l==r就可以返回了
还有那种特殊的情况,要加1
代码如下
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
int l[10005],r[10005];
int s[20005*2];
int sum[20005*8],lazy[20005*8];
int p1,p2,c;
set<int> S;
void Build(int o,int l,int r)
{
lazy[o]=0;
if(l==r) {
sum[o]=0; return ;
}
int mid=l+r>>1;
Build(o<<1,l,mid);
Build(o<<1|1,mid+1,r);
sum[o]=sum[o<<1]+sum[o<<1|1];
}
void push_down(int o,int l,int r)
{
if(lazy[o]) {
lazy[o<<1]=lazy[o<<1|1]=sum[o<<1]=sum[o<<1|1]=lazy[o];
lazy[o]=0;
}
}
void Update(int o,int l,int r)
{
if(p1<=l&&r<=p2) {
sum[o]=lazy[o]=c; return ;
}
push_down(o,l,r);
int mid=l+r>>1;
if(p1<=mid) {
Update(o<<1,l,mid);
}
if(p2>mid) {
Update(o<<1|1,mid+1,r);
}
if(sum[o<<1]==sum[o<<1|1]) {
sum[o]=sum[o<<1];
}
else{
sum[o]=0;
}
}
void Query(int o,int l,int r)
{
if(sum[o]!=0) {
S.insert(sum[o]); return ;
}
if(l==r) {
return ;
}
push_down(o,l,r);
int mid=l+r>>1;
Query(o<<1,l,mid);
Query(o<<1|1,mid+1,r);
}
int main()
{
int t;
scanf("%d",&t);
while(t--) {
S.clear();
int n;
scanf("%d",&n);
int len=0;
for(int i=0;i<n;i++) {
scanf("%d%d",&l[i],&r[i]);
s[len++]=l[i]; s[len++]=r[i];
}
sort(s,s+len);
int L=unique(s,s+len)-s;
for(int i=1;i<L;i++) {
if(s[i]-s[i-1]>1) {
s[len++]=s[i-1]+1;
}
}
sort(s,s+len);
L=unique(s,s+len)-s;
for(int i=0;i<n;i++) {
p1=lower_bound(s,s+L,l[i])-s+1;
p2=lower_bound(s,s+L,r[i])-s+1;
c=i+1;
Update(1,1,L);
}
Query(1,1,L);
printf("%d\n",S.size());
}
}