Color it题解

版权声明:本文为博主原创文章,未经博主允许不得转载。 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  1ax1≤a≤x and  y1by2y1≤b≤y2, then the color  cc should be counted. 

33 : exit. 
InputThe input contains many lines. 

Each line contains a operation. It may be '0', '1 x y c' (  1x,y106,0c501≤x,y≤106,0≤c≤50), '2 x y1 y2' ( 1x,y1,y21061≤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
3
Sample 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;
}

猜你喜欢

转载自blog.csdn.net/Little_Small_Joze/article/details/81051633