翻译:
你喜欢画画吗?小D不喜欢画画,尤其是杂乱的彩色画作。现在小B正在画画。为了防止他画出杂乱的画,小D让你写一个程序来维护以下操作。这些操作的具体格式如下:
0:清除所有的点。
1 x y c:在点(x,y)处添加一个颜色为 c 的点。
2 x y1 y2:统计长方形区域(1,y1)到(x,y2)内不同颜色的数量。也就是说,如果存在一个颜色为 c 的点(a,b),且满足 1<=a<=x 并且 y1<=b<=y2 ,那么颜色应该被统计进去。
3:退出。
输入:
输入包含多行。 每行包含一个操作。可能是 "0"、"1 x y c"、"2 x y1 y2" 或 "3"。操作数都是整数。最后一个操作是3,且只出现一次。 操作1和操作 2 的连续操作最多有 150000 次。 操作 0 最多有10次。
输出:
对于每个操作2,输出一个整数作为答案。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=150005,INF=1e6+5;
struct Segment_Tree{
int rt,tot;
struct Miku{
int lc,rc,val;
}tree[maxn*20];
inline void clear(){for(int i=1;i<=tot;i++)tree[i]={0,0,INF};rt=tot=0;}
inline void pushup(int k){
tree[k].val=INF;
if(tree[k].lc)tree[k].val=min(tree[k].val,tree[tree[k].lc].val);
if(tree[k].rc)tree[k].val=min(tree[k].val,tree[tree[k].rc].val);
}
inline void update(int &k,int l,int r,int x,int v){
if(!k)k=++tot;
if(l==r)return tree[k].val=min(tree[k].val,v),void();
int mid=l+r>>1;
if(x<=mid)update(tree[k].lc,l,mid,x,v);
else update(tree[k].rc,mid+1,r,x,v);
pushup(k);
}
inline int query(int k,int l,int r,int x,int y){
if(!k)return INF;
if(x<=l&&r<=y)return tree[k].val;
int mid=l+r>>1,ret=INF;
if(x<=mid)ret=min(ret,query(tree[k].lc,l,mid,x,y));
if(mid<y)ret=min(ret,query(tree[k].rc,mid+1,r,x,y));
return ret;
}
}T[55];
inline int read(){
int ret=0,f=1;
char c=getchar();
while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
while(isdigit(c)){ret=ret*10+c-'0';c=getchar();}
return ret*f;
}
signed main(){
freopen("Vector_net.out","w",stdout);
for(int i=0;i<=50;i++)T[i].clear();
while(1){
int op=read();
if(op==0){for(int i=0;i<=50;i++)T[i].clear();}
if(op==1){
int x=read(),y=read(),c=read();
T[c].update(T[c].rt,1,INF,y,x);
}
if(op==2){
int x=read(),L=read(),R=read(),ans=0;
for(int i=0;i<=50;i++)
if(T[i].query(T[i].rt,1,INF,L,R)<=x)ans++;
printf("%d\n",ans);
}
if(op==3)break;
}
return 0;
}
样例全过,求 dalao 们救救蒟蒻吧。