版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Little_Small_Joze/article/details/81051633
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.
00 : clear all the points.
11 xx yy cc : add a point which color is cc at point (x,y)(x,y).
22 xx y1y1 y2y2 : count how many different colors in the square (1,y1)(1,y1) and (x,y2)(x,y2). That is to say, if there is a point (a,b)(a,b) colored cc, that 1≤a≤x1≤a≤x and y1≤b≤y2y1≤b≤y2, then the color cc should be counted.
33 : exit.
InputThe input contains many lines.
00 : clear all the points.
11 xx yy cc : add a point which color is cc at point (x,y)(x,y).
22 xx y1y1 y2y2 : count how many different colors in the square (1,y1)(1,y1) and (x,y2)(x,y2). That is to say, if there is a point (a,b)(a,b) colored cc, that 1≤a≤x1≤a≤x and y1≤b≤y2y1≤b≤y2, then the color cc should be counted.
33 : exit.
Each line contains a operation. It may be '0', '1 x y c' ( 1≤x,y≤106,0≤c≤501≤x,y≤106,0≤c≤50), '2 x y1 y2' ( 1≤x,y1,y2≤1061≤x,y1,y2≤106 ) or '3'.
x,y,c,y1,y2x,y,c,y1,y2 are all integers.
Assume the last operation is 3 and it appears only once.
There are at most 150000150000 continuous operations of operation 1 and operation 2.
There are at most 1010 operation 0.
OutputFor 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 3Sample Output
2 3 1 2 2 3 3 1 1 1 1 1 1 1
从空间不足和操作上考虑,决定每种颜色建立一棵线段树。因为查询的时候横坐标左端点是固定的,但是线段树的区间并不是固定一个端点的,如果强行固定一个端点之类的会让解题过程变得更繁琐,所以考虑用y建树。又因为x坐标固定为1,而题目所求是颜色的中数,这说明并不需要将区间内的所有数都搜索一遍,只要找到每种颜色的第一个就可以了,所以记录横坐标最小的那个data。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstring>
#define maxn 1110000
using namespace std;
int lef[maxn*3],rig[maxn*3],root[55],v[maxn*3],cnt,flag,y,x,x1,y1,y2,c;
void updata(int &rot,int l,int r ,int x,int y){
int mid =(r+l)>>1;
if(rot==0) {
rot=++cnt;
v[rot]=x;
}
if(v[rot]>x) v[rot]=x;
if(l==r) return;
if(y<=mid ) updata(lef[rot],l,mid ,x,y);
else updata(rig[rot],mid +1,r,x,y);
}
void qry(int rot,int l,int r){
int mid = (l+r)>>1;
if(flag || rot==0) return ;
if(l >= y1 && r<=y2){
if(v[rot]<=x1) flag=1;
return ;
}
if(y1 <= mid) qry(lef[rot],l,mid );
if(y2 >= mid +1) qry(rig[rot],mid+1,r);
}
int main(){
int oprt,ans;
// freopen("a.txt","r",stdin);
while(~scanf("%d",&oprt )!=EOF){
if(oprt==3) break;
if(oprt==0){
for(int i=1;i<=cnt;i++)
lef[i]=rig[i]=0;
memset(root,0,sizeof(root));
cnt=0;
}else if( oprt==1){
scanf("%d%d%d",&x,&y,&c);
updata(root[c],1,maxn,x,y);
}else if(oprt==2){
scanf("%d%d%d",&x1,&y1,&y2);
ans=0;
for(int i=0;i<=50;i++){
flag=0;
qry(root[i],1,maxn);
ans+=flag;
}
printf("%d\n",ans);
}
}
return 0;
}