这道题容易陷入权值线段树的怪圈
其实不然,题目问的是有多少种颜色,我们只需查到各种颜色,在[y1,y2]中横坐标的最小值就行,判断其小不小于X
需要动态开点
#include<bits/stdc++.h>
const int C=55;
const int D=1e6+5;
const int N=4e6+5;
using namespace std;
int rt[55],tot,val[N],lson[N],rson[N],flag;
template<class T>
inline void read(T &x)
{
x=0;
static char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
}
void update(int &now,int l,int r,int p,int x)
{
if(!now) now=++tot;
if(l==r)
{
val[now]=min(val[now],x);
return;
}
int m=(l+r)>>1;
if(p<=m) update(lson[now],l,m,p,x);
else update(rson[now],m+1,r,p,x);
val[now]=min(val[lson[now]],val[rson[now]]);
}
void query(int now,int l,int r,int ql,int qr,int x)
{
if(!now||flag) return;
if(ql<=l&&r<=qr)
{
if(val[now]<=x) flag=1;
return;
}
int m=(l+r)>>1;
if(ql<=m) query(lson[now],l,m,ql,qr,x);
if(qr>m) query(rson[now],m+1,r,ql,qr,x);
}
inline void Clear()
{
memset(rt,0,sizeof(rt));
memset(lson,0,sizeof(lson));
memset(rson,0,sizeof(rson));
for(int i=0;i<N;i++) val[i]=D;
tot=0;
}
void print(int x)
{
if(x>9) print(x/10);
putchar(x%10+'0');
}
int main()
{
int opt;
for(int i=0;i<N;i++) val[i]=D;
while(cin>>opt)
{
if(opt==0) Clear();
int x,y,z,k;
if(opt==1)
{
read(x); read(y); read(k);
update(rt[k],1,D,y,x);
}
if(opt==2)
{
read(x); read(y); read(z);
if(y>z) swap(y,z);
int ans=0;
for(int i=0;i<=50;i++)
{
flag=0;
query(rt[i],1,D,y,z,x);
if(flag) ans++;
}
print(ans);
putchar('\n');
}
if(opt==3) return 0;
}
return 0;
}