【刷题】HDU 6183 Color it

Problem Description

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

Description(CHN)

(1~x~y~c) :在 ((x,y)) 点涂上c这种颜色
(2~x~y_1~y_2) :从矩形左下角 ((1,y_1)) 到矩形右上角 ((x,y_2)) 范围内有多少种颜色
(0) :清空
(3) :表示退出

Solution

考虑对每一种颜色建一棵线段树
询问时枚举每一种颜色,看是否存在矩阵中
因为询问一定是从 (x=1) 开始,所以对于一种颜色,线段树位置 (i) 表示矩形 (y=i) 的那一列中当前颜色出现的最小 (x) 是什么,再与询问的条件比较即可
空间开不下,用动态开点

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=1000000+10,inf=0x3f3f3f3f;
int opt,N=MAXN,C=50,na;
template<typename T> inline void read(T &x)
{
	T data=0,w=1;
	char ch=0;
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')w=-1,ch=getchar();
	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
	x=data*w;
}
template<typename T> inline void write(T x,char ch='')
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
	if(ch!='')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return (x<y?x:y);}
template<typename T> inline T max(T x,T y){return (x>y?x:y);}
#define Mid ((l+r)>>1)
#define lson l,Mid
#define rson Mid+1,r
struct Segment_Tree{
	int Mn[MAXN<<2],lc[MAXN<<2],rc[MAXN<<2],cnt,root[50+10];
	inline void init()
	{
		for(register int i=0;i<=cnt;++i)lc[i]=rc[i]=0;
		memset(root,0,sizeof(root));
		cnt=0;
	}
	inline void Update(int &rt,int l,int r,int ps,int k)
	{
		if(!rt)Mn[rt=++cnt]=k;
		else chkmin(Mn[rt],k);
		if(l==r)return ;
		else
		{
			if(ps<=Mid)Update(lc[rt],lson,ps,k);
			else Update(rc[rt],rson,ps,k);
		}
	}
	inline void Query(int rt,int l,int r,int L,int R,int lt)
	{
		if(!rt||na)return ;
		if(L<=l&&r<=R)na=(Mn[rt]<=lt);
		else
		{
			if(L<=Mid)Query(lc[rt],lson,L,R,lt);
			if(R>Mid)Query(rc[rt],rson,L,R,lt);
		}
	}
};
Segment_Tree T;
#undef Mid
#undef lson
#undef rson
int main()
{
	while(scanf("%d",&opt)!=EOF&&opt!=3)
	{
		if(opt==0)T.init();
		if(opt==1)
		{
			int x,y,c;read(x);read(y);read(c);
			T.Update(T.root[c],1,N,y,x);
		}
		if(opt==2)
		{
			int x,y1,y2,ans=0;read(x);read(y1);read(y2);
			if(y1>y2)std::swap(y1,y2);
			for(register int i=0;i<=C;++i)na=0,T.Query(T.root[i],1,N,y1,y2,x),ans+=na;
			write(ans,'
');
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/hongyj/p/9424415.html