一、hash表
hash表给线段树的某段线段加上一个状态,并且该状态可以被新状态覆盖
在此题,每个状态就是一种海报
二、离散化处理
1、比如:1-10 1-4 5-10 可离散为1-4 1-2 3-4,有效减少了复杂度
2、有个问题:
如:a序列1-10 1-4 5-10; b序列:1-10 1-4 6-10
若都离散为1-4 1-2 3-4,则a中线段一被完全覆盖,而b中却没有完全覆盖
解决:对于离散数组中的相邻两数字,若间距大于1,则在其中加上一个他们之间的数字
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 10010;
bool hash_[maxn];
int li[maxn], ri[maxn];
int disc[maxn<<2];//离散化表,用下标来离散值;左坐标加右坐标所以乘以二,又要在两个不连续的数据之间加一个数据,所以又乘以二
int mark[maxn<<4];//(maxn<<2)<<2;
int cnt;
int bin_search(int key, int n);
void update(int L, int R, int x, int l, int r, int rt);
void pushdown(int rt);
void query(int l, int r, int rt);
int main()
{
int i;
int t, n;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
int tcnt = 0;
//将数据输入离散表
for(i = 0; i < n; ++i)
{
scanf("%d %d", &li[i], &ri[i]);
disc[tcnt++] = li[i];
disc[tcnt++] = ri[i];
}
sort(disc, disc + tcnt);
//进行处理:去重和加入中间值
int m = 1;
for(i = 1; i < tcnt; ++i)
if(disc[i] != disc[i - 1])
disc[m++] = disc[i];
for(i = m - 1; i > 0; --i)
if(disc[i] != disc[i - 1] + 1)
disc[m++] = disc[i - 1] + 1;
sort(disc, disc + m);
memset(mark, -1, sizeof(mark));
for(i = 0; i < n; ++i)
{
int l = bin_search(li[i], m);
int r = bin_search(ri[i], m);
update(l, r, i, 0, m, 1);
}
cnt = 0;
memset(hash_, 0, sizeof(hash_));
query(0, m, 1);
printf("%d\n", cnt);
}
return 0;
}
void query(int l, int r, int rt)
{
if(~mark[rt])
{
if(!hash_[mark[rt]]) ++cnt;
hash_[mark[rt]] = 1;
return;
}
if(l == r) return;
int mid = (l + r)>>1;
query(l, mid, rt<<1);
query(mid + 1, r, rt<<1|1);
}
void pushdown(int rt)
{
if(mark[rt] == -1) return;
mark[rt<<1] = mark[rt<<1|1] = mark[rt];
mark[rt] = -1;
}
void update(int L, int R, int x, int l, int r, int rt)
{
if(L <= l && r <= R)
{
mark[rt] = x;
return;
}
pushdown(rt);
int mid = (l + r)>>1;
if(L <= mid) update(L, R, x, l, mid, rt<<1);
if(R >= mid + 1) update(L, R, x, mid + 1, r, rt<<1|1);
}
int bin_search(int key, int n)
{
int l = 0, r = n - 1;
while(l <= r)
{
int mid = (l + r)>>1;
if(disc[mid] == key) return mid;
if(disc[mid] < key) l = mid + 1;
else r = mid - 1;
}
return -1;
}