线段树+离散化的问题。
Mayor’s posters
题目传送:POJ - 2528 - Mayor’s posters
参考胡浩的写法。
AC代码:
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;
const int maxn = 12345;
bool Hash[maxn];
int li[maxn], ri[maxn];//记录输入海报的左右位置
int X[maxn * 3], cx;//记录输入的所有位置以及对应位置个数
int col[maxn << 4];//用颜色标记海报,-1表示该区间有多种海报(颜色)
int ans;
int n;
int b_search(int key, int n, int X[]) {//二分查找
int l = 0, r = n - 1;
while(l <= r) {
int m = (l + r) >> 1;
if(X[m] == key) return m;
if(X[m] < key) l = m + 1;
else r = m - 1;
}
return -1;
}
void pushdown(int rt) {
if(col[rt] != -1) {
col[rt << 1] = col[rt << 1 | 1] = col[rt];
col[rt] = -1;
}
}
void update(int rt, int l, int r, int c, int L, int R) {//插入
if(L <= l && r <= R) {
col[rt] = c;
return;
}
pushdown(rt);
int mid = (l + r) >> 1;
if(L <= mid) update(rt << 1, l, mid, c, L, R);
if(R >= mid + 1) update(rt << 1 | 1, mid + 1, r, c, L, R);
}
void query(int rt, int l, int r) {//查询,带hash判重
if(col[rt] != -1) {
if(!Hash[col[rt]]) {
ans ++;
Hash[col[rt]] = true;
}
return;
}
if(l == r) return;
int mid = (l + r) >> 1;
query(rt << 1, l, mid);
query(rt << 1 | 1, mid + 1, r);
}
int main() {
int T;
scanf("%d", &T);
while(T --) {
scanf("%d", &n);
cx = 0;
for(int i = 0; i < n; i ++) {
scanf("%d %d", &li[i], &ri[i]);
X[cx ++] = li[i];
X[cx ++] = ri[i];
}
sort(X, X + cx);
int m = 1;
for(int i = 1; i < cx; i ++) {//去重
if(X[i] != X[i - 1]) X[m ++] = X[i];
}
for(int i = m - 1; i > 0; i --) {//解决相邻数字大于1的问题,通过插入一个数字
if(X[i] != X[i - 1] + 1) X[m ++] = X[i - 1] + 1;
}
sort(X, X + m);
memset(col, -1, sizeof(col));
for(int i = 0; i < n; i ++) {
int l = b_search(li[i], m, X);//二分查找离散化之后对应的那个值
int r = b_search(ri[i], m, X);
update(1, 0, m, i, l, r);
}
ans = 0;
memset(Hash, 0, sizeof(Hash));
query(1, 0, m);
printf("%d\n", ans);
}
return 0;
}