题目
Color it
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 872 Accepted Submission(s): 265
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.
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.
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
题意
给我一个区间让我们求出这个区间内有多少个不同的颜色
解题思路
第一次做用的二分TLE , 本题用的线段树,离散化的方式储存了51棵虚树 ,因为只有51个点,构建51棵树, 我们只需要维护纵坐标就可以了 , 因为横坐标固定了一个,只有一个横坐标是变化的,这样子这个题就有点像区间内求最小值的问题,只是在这里变成了区间(纵坐标的区间)内求最近的横坐标,相互转化一下就可以了,这里的离散化处理很值得学习,数据结构学的东西都还给老师了真是惭愧。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
const int maxn = 1000000 + 10 ;
int x , y , yc , cnt , flag , root[55] , lson[maxn] , rson[maxn] , v[maxn] ;
void update(int &node , int l , int r )
{
int mid = (l + r) >> 1 ;
if(!node)
{
node = cnt ;
lson[node] = 0 ;
rson[node] = 0 ;
v[cnt++] = x ;
}
v[node] = min(v[node] , x) ;
if(l == r)
return ;
if(y <= mid)
update(lson[node] , l , mid ) ;
else
update(rson[node] , mid + 1 , r ) ;
}
void query(int node , int l , int r)
{
if(flag || !node)
return ;
if(y <= l && r <= yc)
{
if(v[node] <= x)
flag = 1 ;
return ;
}
int mid = (l + r) >> 1 ;
if(y <= mid) ///愚了愚了 记错了 给写颠倒了
query(lson[node] , l , mid) ;
if(yc > mid)
query(rson[node] , mid + 1 , r) ;
}
int main()
{
int ca ;
cnt = 1 ;
memset(root , 0 , sizeof(root)) ;
while(scanf("%d" , &ca) && ca != 3)
{
if(ca == 0) {
memset(root , 0 , sizeof(root)) ;
cnt = 1 ; continue ;
}
scanf("%d %d %d" , &x , &y , &yc) ;
if(ca == 1)
{
update(root[yc] , 1 , 1000000) ;
}
if(ca == 2)
{
int ans = 0 ;
for(int i = 0 ; i<= 50 ; i++)
{
flag = 0 ;
query(root[i] , 1 , 1000000) ;
ans += flag ;
}
printf("%d\n" , ans) ;
}
}
return 0 ;
}