#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#define LL long long
#define inf 0x7fffffff
#define N 10500
using namespace std; //poj2528
/*
题意:一面墙上贴海报,问最后能看到多少张海报(海报高度一样,宽度不一样)
思路:先要离散化处理数据,并且如果两个点不相邻距离>1(排完序后),则要在这两个点间再加一个点,最后用线段树处理
*/
struct line
{
int xi, xr;
}a[N];
struct node
{
int l, r, cover;
}p[N*12];
int point[N*8], vis[N*8], s[10000005];
void build(int L, int R, int n)
{
p[n].l=L;
p[n].r=R;
p[n].cover=0;
if(L==R)
return ;
int mid=(L+R)>>1;
build(L, mid, n<<1);
build(mid+1, R, n<<1|1);
return ;
}
void pushdown(int x)
{
int lson=x<<1, rson=x<<1|1;
if(p[x].cover)
{
p[lson].cover=p[rson].cover=p[x].cover;
p[x].cover=0;
}
return ;
}
void pushup(int n)
{
int lson=n<<1, rson=n<<1|1;
if(p[lson].cover==p[rson].cover)
p[n].cover=p[lson].cover;
return ;
}
void update(int k, int l, int r, int L, int R, int n)
{
if(l<=L&&R<=r)
{
p[n].cover=k;
return ;
}
pushdown(n);
int mid=(L+R)>>1;
if(r<=mid)
update(k, l, r, L, mid, n<<1);
else if(l>mid)
update(k, l, r, mid+1, R, n<<1|1);
else
{
update(k, l, mid, L, mid, n<<1);
update(k, mid+1, r, mid+1, R, n<<1|1);
}
pushup(n);
return ;
}
int query(int l, int r, int n)
{
int ans=0;
if(p[n].cover)
{
if(!vis[p[n].cover]) //之前没有扫描过的画
{
vis[p[n].cover]=1;
return 1;
}
else return 0;
}
if(l==r)return 0; //记得要有这句
pushdown(n);
int mid=(l+r)>>1;
ans+=query(l, mid, n<<1);
ans+=query(mid+1, r, n<<1|1);
return ans;
}
int main()
{
int n, m, t, T, k;
vector<int> point;
vector<int>::iterator iter;
scanf("%d", &T);
while(T--)
{
point.clear();
scanf("%d", &n);
for(t=0; t<n; ++t)
{
scanf("%d%d", &a[t].xi, &a[t].xr);
point.push_back(a[t].xi);
point.push_back(a[t].xr);
}
sort(point.begin(), point.end());
iter=unique(point.begin(), point.end()); //将vector内相同的元素放到数组后面,返回的是不同元素数组的最后位置
point.erase(iter, point.end()); //删除掉相同的元素
m=point.size();
s[point[0]]=1;
for(t=k=1; t<m; ++t)
{
if(point[t]-point[t-1]>1)
s[point[t]-1]=++k;
s[point[t]]=++k;
}
build(1, k, 1);
for(t=0; t<n; ++t)
update(t+1, s[a[t].xi], s[a[t].xr], 1, k, 1); //从头开始覆盖
memset(vis, 0, sizeof(vis));
int ans=query(1, k, 1);
printf("%d\n", ans);
}
return 0;
}
poj2528离散化处理数据 线段树
最新推荐文章于 2020-06-26 18:02:33 发布