讲道理我之前暂时跳过染色的题是因为总觉得有什么很高端的算法来query
直到我做了F题(
#include <cstdio> #include <cstring> #include <algorithm> #define INF 0x3f3f3f3f #define mem(str,x) memset(str,(x),sizeof(str)) #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; typedef long long LL; const int MAXN = 10005; int n, hash[MAXN<<3], col[MAXN<<4]; int ans, li[MAXN], ri[MAXN]; bool vis[MAXN]; inline void push_down(int rt){ if(~col[rt]){ col[rt<<1] = col[rt<<1|1] = col[rt]; col[rt] = -1; } } void update(int L, int R, int c, int l, int r, int rt) { if(L <= l && R >= r){ col[rt] = c; //printf("%d - %d : %d ", l, r, c); return; } push_down(rt); int m = (l + r) >> 1; if(L <= m) update(L, R, c, lson); if(R > m) update(L, R, c, rson); } void query(int l, int r, int rt) { if(l == r){ if(!vis[col[rt]] && ~col[rt]){ //printf("%d at %d ", col[rt], l); ans++; vis[col[rt]] = true; } return; } push_down(rt); int m = (l + r) >> 1; query(lson); query(rson); } int binary_search(int l, int r, int c) { int m; while(l <= r){ m = (l + r) >> 1; if(hash[m] == c) return m; else if(hash[m] > c) r = m - 1; else l = m + 1; } return -1; } int main() { int t; scanf("%d", &t); while(t--){ mem(col, -1); mem(vis, false); scanf("%d", &n); int nn = 0, mm = 1; for(int i = 1; i <= n; i++){ scanf("%d%d", &li[i], &ri[i]); hash[++nn] = li[i]; hash[++nn] = ri[i]; } sort(hash+1, hash+1+nn); //去除重复数据 for(int i = 2; i <= nn; i++){ if(hash[i] != hash[i-1]) hash[++mm] = hash[i]; } //在相距超过1的点之间插入一个点防止覆盖 for(int i = mm; i > 1; i--){ if(hash[i] - hash[i-1] > 1) hash[++mm] = hash[i] - 1; } sort(hash+1, hash+1+mm); //离散化构造线段树 for(int i = 1; i <= n; i++){ int l = binary_search(1, mm, li[i]); int r = binary_search(1, mm, ri[i]); update(l, r, i, 1, mm, 1); //printf("%d - %d : %d ", l, r, i); } ans = 0; query(1, mm, 1); printf("%d ", ans); } return 0; }