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
题意:操作0 表示清空,操作1 x y c 就是在x,y点涂上c这种颜色,操作 2 x y1 y2表示从矩形左下角(1,y1)到矩形右上角(x,y2)范围内有多少种颜色,3表示退出
题解:x,y的范围都在1e6 不能用二维线段树,数据量为150000,也不能离散化,因为查询时x的范围都是从1开始的,因此我们可以以y坐标建立一维的线段树,表示区间存在的最小的x坐标,但是51*1e6*4内存是不够的,但数据量最多为150000,因此我们可以动态开点就可以了,最多150000*log(150000)这样就很可观了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define lowbit(x) x&(-x)
const int N = 150000+10;
const int mod = 1000000007;
int lson[N * 20], rson[N * 20];
int root[55], cnt;
int pos[N * 20];
void init() {
for(int i = 0; i <= cnt; i++) {
lson[i] = rson[i] = 0;
}
for(int i = 0; i <= 50; i++)
root[i] = 0;
cnt = 0;
}
int build(int x)
{
cnt++;
pos[cnt] = x;
return cnt;
}
void update(int cur, int l, int r, int y, int x)
{
pos[cur] = min(pos[cur], x);
if(l == r) return;
int mid = (r + l) >> 1;
if(y <= mid) {
if(!lson[cur]) lson[cur] = build(x);
update(lson[cur], l, mid, y, x);
} else {
if(!rson[cur]) rson[cur] = build(x);
update(rson[cur], mid + 1, r, y, x);
}
}
int flag;
void query(int pl, int pr, int cur, int l, int r, int x) {
if(cur == 0 || flag) return;
if(pl <= l && r <= pr) {
if(pos[cur] <= x) flag = 1;
return;
}
int mid = (l + r) >> 1;
if(pl <= mid) query(pl, pr, lson[cur], l, mid, x);
if(pr > mid) query(pl, pr, rson[cur], mid + 1, r, x);
}
int main()
{
int op;
int x, y, c;
int y1, y2;
int ans;
while(~scanf("%d", &op)) {
if(op == 0) init();
if(op == 1) {
scanf("%d %d %d", &x, &y, &c);
if(!root[c]) root[c] = build(x);
update(root[c], 1, 1000000, y, x);
}
if(op == 2) {
scanf("%d %d %d", &x, &y1, &y2);
ans = 0;
for(int i = 0; i <= 50; i++) {
flag = 0;
query(y1, y2, root[i], 1, 1000000, x);
ans += flag;
// if(flag) cout<<i<<endl;
}
printf("%d\n", ans);
}
if(op == 3) break;
}
return 0;
}
昭哥还有一种暴力的写法,应该就是数据不够给力吧
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define lowbit(x) x&(-x)
const int N = 150000+10;
const int mod = 1000000007;
vector<pair<int,int> > v[55];
void init() {
for(int i = 0; i <= 50; i++) v[i].clear();
}
int main()
{
int op;
int x, y, c;
int y1, y2;
int ans;
while(~scanf("%d", &op)) {
if(op == 0) init();
if(op == 1) {
scanf("%d %d %d", &x, &y, &c);
v[c].push_back(make_pair(x,y));
}
if(op == 2) {
scanf("%d %d %d", &x, &y1, &y2);
ans = 0;
for(int i = 0; i <= 50; i++) {
for(int j = 0; j < v[i].size(); j++)
{
if(v[i][j].first <= x && v[i][j].second <= y2 && v[i][j].second >= y1){
ans++;
break;
}
}
}
printf("%d\n", ans);
}
if(op == 3) break;
}
return 0;
}