Color it
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 629 Accepted Submission(s): 167
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
题意:
一个空的坐标系,有④种操作:①1 x y c表示在(x, y)点染上颜色c;②2 X y1 y2表示查询在(1, y1)到(X, y2)范围内有多少种不同的颜色:
③0表示清屏;④3表示程序退出(0<=x, y<=1000000, 0<=c<=50)
主要就是前两个操作,因为颜色数量较少,所以给每种颜色建立一颗线段树然后暴力查找,但是又不能以整个坐标系建树,考虑到题目条件一定包含坐标横坐标1
那么就可以只建Y坐标轴包存离y轴最近的点的坐标
这题的操作也是骚的一逼,线段树和主席树的变种操作
#include<iostream> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<vector> #include<map> #include <set> #include <bits/stdc++.h> using namespace std; const int N = 200000+10; typedef long long LL; int rt[55], ls[N*20], rs[N*20], val[N*20], cnt; void add(int &o,int x,int y,int l,int r) { if(o==0) o=++cnt,val[o]=x; if(val[o]==0||val[o]>x) val[o]=x; if(l==r) return ; int mid=(l+r)/2; if(y<=mid) add(ls[o],x,y,l,mid); else add(rs[o],x,y,mid+1,r); return ; } int flag; void query(int o,int X,int L,int R,int l,int r) { if(o==0||flag) return ; if(l>=L&&r<=R) { if(val[o]<=X) flag=1; return ; } int mid=(l+r)/2; if(L<=mid) query(ls[o],X,L,R,l,mid); if(R>mid) query(rs[o],X,L,R,mid+1,r); return ; } int main() { memset(rt,0,sizeof(rt)); memset(ls,0,sizeof(ls)); memset(rs,0,sizeof(rs)); cnt=0; int q; while(scanf("%d", &q)) { if(q==1) { int x, y, z; scanf("%d %d %d", &x, &y, &z); add(rt[z],x,y,1,1000000); } else if(q==2) { int x, y1, y2, ans=0; scanf("%d %d %d", &x, &y1, &y2); for(int i=0; i<=50; i++) { flag=0; query(rt[i],x,y1,y2,1,1000000); ans+=flag; } printf("%d\n",ans); } else if(q==0) { memset(rt,0,sizeof(rt)); memset(ls,0,sizeof(ls)); memset(rs,0,sizeof(rs)); cnt=0; } else break ; } return 0; }