HDU6183- Color it (线段树 动态开点)
Description
要求你实现一个画板支持以下操作:
- 0 清空画板
- 1 x y c 在位置(x, y)添加颜色c
- 2 x y1 y2 求矩形区域(1, y1)到(x, y2)不同颜色的个数。
- 3 结束
\((1≤x,y,y1,y2≤10^6,0≤c≤50)\)
思路
每种颜色一棵线段树,搞51棵线段树。线段树保存区间[y1,y2]中最小的\(x_0\)。只要询问的x在区间[y1,y2]大于等于\(x_0\),说明这个区间至少包含这种颜色。
这题时间和空间都卡得很紧。要动态开点。其实很简单,就多个l,r数组存储左右子节点的编号。然后线段树实现尽可能优化,减少不必要的更新即可。
思考
这题貌似相同点的颜色不会被覆盖,写的时候没考虑。有时间考虑一下怎么做。
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <cstring>
#include <string>
#include <deque>
#include <cmath>
#include <iomanip>
#include <cctype>
#define endl '\n'
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FILE freopen("..//data_generator//in.txt","r",stdin),freopen("res.txt","w",stdout)
#define FI freopen("..//data_generator//in.txt","r",stdin)
#define FO freopen("res.txt","w",stdout)
#define pb push_back
#define mp make_pair
#define seteps(N) fixed << setprecision(N)
typedef unsigned long long ull;
typedef long long ll;
using namespace std;
/*-----------------------------------------------------------------*/
#define INF 0x3f3f3f3f
const int N = 1e7 + 10;
const double eps = 1e5;
typedef pair<ll, ll> PII;
int root[100];
int minn[N];
int lc[N];
int rc[N];
int si;
void renew(int l, int r, int p, int val, int &rt) {
if(!rt) {
rt = ++si;
minn[rt] = INF;
lc[rt] = rc[rt] = 0;
}
minn[rt] = min(minn[rt], val);
if(l == r) return ;
int mid = (l + r) / 2;
if(p <= mid) {
renew(l, mid, p, val, lc[rt]);
}
else {
renew(mid + 1, r, p, val, rc[rt]);
}
}
bool query(int l, int r, int L, int R, int val ,int rt) {
if(!rt) return false;
if(L <= l && R >= r) {
return minn[rt] <= val;
}
if(minn[rt] > val) return false;
int mid = (l + r) / 2;
if(mid >= L)
if(query(l, mid, L, R, val, lc[rt])) return true;
if(mid < R)
if(query(mid + 1 ,r ,L, R,val, rc[rt])) return true;
return false;
}
int main() {
IOS;
int op;
while(cin >> op) {
if(op == 3) break;
if(op == 0) {
si = 0;
memset(root, 0, sizeof root);
}
else if(op == 1) {
int x, y, c;
cin >> x >> y >> c;
renew(1, 1000000, y, x, root[c]);
}
else if(op == 2) {
int x, y1, y2;
cin >> x >> y1 >> y2;
int ans = 0;
for(int i = 0; i <= 50; i++) {
if(query(1, 1000000, y1, y2, x, root[i])) ans++;
}
cout << ans << endl;
}
}
}