Do you like painting? Little D doesn't like painting, especially messy color paintings. Now Little B is painting. To prevent him from drawing messy painting, Little D asks you to write a program to maintain following operations. The specific format of these operations is as follows.
0 : clear all the points.
1 x y c : add a point which color is c at point (x,y).
2 x y1 y2 : count how many different colors in the square (1,y1)and (x,y2). That is to say, if there is a point (a,b) colored c, that 1≤a≤x and y1≤b≤y2 then the color c should be counted.
3: exit.
Input
The input contains many lines.
Each line contains a operation. It may be '0', '1 x y c' ( 1≤x,y≤106,0≤c≤50 ), '2 x y1 y2' (1≤x,y1,y2≤106 ) or '3'.
x,y,c,y1,y2 are all integers.
Assume the last operation is 3 and it appears only once.
There are at most 150000 continuous operations of operation 1 and operation 2.
There are at most 10 operation 0.
Output
For each operation 2, output an integer means the answer .
Sample Input
0
1 1000000 1000000 50
1 1000000 999999 0
1 1000000 999999 0
1 1000000 1000000 49
2 1000000 1000000 1000000
2 1000000 1 1000000
0
1 1 1 1
2 1 1 2
1 1 2 2
2 1 1 2
1 2 2 2
2 1 1 2
1 2 1 3
2 2 1 2
2 10 1 2
2 10 2 2
0
1 1 1 1
2 1 1 1
1 1 2 1
2 1 1 2
1 2 2 1
2 1 1 2
1 2 1 1
2 2 1 2
2 10 1 2
2 10 2 2
3
Sample Output
2
3
1
2
2
3
3
1
1
1
1
1
1
1
线段树,大体思路:有51种颜色,所以建立51棵线段树,因为横坐标范围是1-x,只要在y1-y2内查询颜色的点横坐标的最小值小于等于x即可,维护区间为y1-y2,维护的值为该区间颜色的x的最小值 。
AC的C++程序如下:
#include<cstdio>
#include<cstring>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int N=1e6+10;
int root[51],cnt=0,fg; //root代表每种颜色的根结点
int le[4*N],ri[4*N];//存放每个结点的左右子结点
int Min[4*N];//存放每个结点x的最小值
inline void init()
{
memset(root,0,sizeof(root));
le[0]=0,ri[0]=0,cnt=0,Min[0]=inf;
}
inline void push_up(int rt)
{
Min[rt]=min(Min[le[rt]],Min[ri[rt]]);
}
inline void update(int &rt,int l,int r,int L,int val)
{
if(rt==0)
{
rt=++cnt;
le[rt]=0;
ri[rt]=0;
Min[rt]=val;
}
if(l==r)
{
Min[rt]=min(Min[rt],val);
return;
}
int mid=(l+r)>>1;
if(L<=mid) update(le[rt],l,mid,L,val);
else update(ri[rt],mid+1,r,L,val);
push_up(rt);
}
inline void query(int rt,int a,int b,int l,int r,int val)
{
if(fg||rt==0) return;
if(a<=l&&b>=r)
{
if(Min[rt]<=val) fg=1;
return;
}
int mid=(l+r)>>1;
if(a<=mid) query(le[rt],a,b,l,mid,val);
if(b>mid) query(ri[rt],a,b,mid+1,r,val);
}
int main()
{
int op;
while(~scanf("%d",&op))
{
if(op==3) break;
if(op==0) init();
else if(op==1)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
update(root[c],1,N,y,x);
}
else
{
int x,y1,y2;
scanf("%d%d%d",&x,&y1,&y2);
int ans=0;
for(int i=0;i<=50;i++)
{
fg=0;
query(root[i],y1,y2,1,N,x);
ans+=fg;
}
printf("%d\n",ans);
}
}
}

4万+

被折叠的 条评论
为什么被折叠?



