Color it
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 579 Accepted Submission(s): 153
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
Source
有四种操作:
0:清除所有点
1 x y c : 给点(x, y)添加一种颜色c(颜色不会覆盖)
2 x y1 y2 : 在(0, y1)与(x, y2)所围成的矩形里有多少种颜色
3 : 程序结束
解题思路:颜色最多51种。我们就建51棵线段树。 每个线段树按y轴建树,每个结点的值是在范围内的最小的x值
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <cmath>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
int s[55], L[1000009], R[1000009], v[1000009];
int tot, x, y, w, yy1, yy2, flag;
void update(int &k, int l, int r, int y, int x)
{
if (!k)
{
L[k = tot] = 0, R[tot++] = 0;
v[k] = x;
}
v[k] = min(v[k], x);
if (l == r) return;
int mid = (l + r) >> 1;
if (y <= mid) update(L[k], l, mid, y, x);
else update(R[k], mid + 1, r, y, x);
}
void query(int k, int l, int r, int ll, int rr)
{
if (flag || !k) return;
if (ll <= l && rr >= r)
{
if (v[k] <= x) flag = 1;
return;
}
int mid = (l + r) >> 1;
if (ll <= mid) query(L[k], l, mid, ll, rr);
if (rr > mid) query(R[k], mid + 1, r, ll, rr);
}
int main()
{
int p;
while (~scanf("%d", &p))
{
if (p == 3) break;
if (p == 0)
{
memset(s, 0, sizeof s);
tot = 1;
}
else if (p == 1)
{
scanf("%d%d%d", &x, &y, &w);
update(s[w], 1, 1000000, y, x);
}
else if (p == 2)
{
scanf("%d%d%d", &x, &yy1, &yy2);
int ans = 0;
for (int i = 0; i <= 50; i++)
{
flag = 0;
query(s[i], 1, 1000000, yy1, yy2);
if (flag) ans++;
}
printf("%d\n", ans);
}
}
return 0;
}