Mayor's posters(线段树 + 离散化 + 区间染色)
记录一下,毕竟要开到套题里面,这题细节比较多
首先是一个空间问题,N只有1e4但是你离散化后,每个区间两倍。还有一些奇怪的东西加进来,空间得开够
[1, 10], [1, 4], [5, 10] 离散化处理后 -> [1, 4], [1, 2], [3, 4]
[1, 10], [1, 4], [6, 10] 离散化处理后 -> [1, 4], [1, 2], [3, 4], 第二组离散化前能看到三张,离散化后出来就只能看到两张了,
这里我们在读入每一个r后面都再添加一个r + 1, 保证离散化后k大值不同即可。
剩下的就是线段树细节了,由于只是一个统计数量,直接lazy充当线段树数组就够了
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1e5 + 10;
int Li[N], Ri[N];
int a[N << 3], lazy[N << 3], cnt, idx;
bool mp[N];
void push_down(int rt)
{
if(lazy[rt] == -1) return;
int ch = rt << 1;
lazy[ch] = lazy[rt];
lazy[ch + 1] = lazy[rt];
lazy[rt] = -1;
}
void change(int rt, int l, int r, int L, int R, int c)
{
if(l >= L && r <= R)
{
lazy[rt] = c;
return;
}
push_down(rt);
int ch = rt << 1;
int mid = l + r >> 1;
if(L <= mid) change(ch, l, mid, L, R, c);
if(R > mid) change(ch + 1, mid + 1, r, L, R, c);
}
void query(int rt, int l, int r)
{
if(l == r && lazy[rt] != -1)
{
if(!mp[lazy[rt]] && lazy[rt] != -1)
{
mp[lazy[rt]] = 1;
cnt++;
}
return;
}
push_down(rt);
int ch = rt << 1;
int mid = l + r >> 1;
query(ch, l, mid);
query(ch + 1, mid + 1, r);
}
signed main()
{
int T;
scanf("%d", &T);
while(T--)
{
cnt = idx = 0;
memset(lazy, -1, sizeof lazy);
memset(mp, 0, sizeof mp);
int n;
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
{
scanf("%d %d", &Li[i], &Ri[i]);
a[idx++] = Li[i];
a[idx++] = Ri[i];
a[idx++] = Ri[i] + 1;
}
sort(a + 1, a + 1 + idx);
int m = unique(a + 1, a + 1 + idx) - a - 1;
for(int i = 1; i <= n; ++i)
{
int l = lower_bound(a + 1, a + m, Li[i]) - a;
int r = lower_bound(a + 1, a + m, Ri[i]) - a;
change(1, 1, m, l, r, i);
}
query(1, 1, m);
printf("%d\n", cnt);
}
return 0;
}

浙公网安备 33010602011771号