poj 2528 (线段树+离散化)
poj 2528
For each input data set print the number of visible posters after all the posters are placed.
The picture below illustrates the case of the sample input.
![]()
The picture below illustrates the case of the sample input.

Sample Input
1 5 1 4 2 6 8 10 3 4 7 10
Sample Output
4
题意:贴报纸,可以互相覆盖,求最后能看见多少。
数据很大,不离散会超出内存。将浪费的部分去掉,将出现过的所有点其映射到相距更近的点上。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define N 100005
#define mod 258280327
#define MIN 0
#define MAX 1000001
int l[N],r[N];
int x[N];
int has[10000005];
struct node
{
int le,re;
bool covered;
} pnode[10*N];
void build(int i,int l,int r)
{
pnode[i].le = l;
pnode[i].re = r;
pnode[i].covered = false;
if(l == r)
return;
build(2 * i,l,(l+r)/2);
build(2*i+1,(l+r)/2+1,r);
}
bool insert(int i,int l,int r,int a,int b)//是否可见
{
if(pnode[i].covered == true)//如果要找的已经被覆盖
return false;
if(l == a && r == b)
{
pnode[i].covered = true;
return true;
}
bool ans;
int mid = (l + r)>>1;
if (mid >= b)
ans = insert(i*2,l, mid, a, b);
else if (mid < a)
ans = insert(i*2+1,mid+1, r, a, b);
else
{
bool x1 = insert(i*2,l, mid, a, mid);
bool x2 = insert(i*2+1,mid+1, r, mid+1, b);
ans = x1 || x2;
}
if(pnode[i*2].covered == true && pnode[i*2+1].covered == true)
pnode[i].covered = true;
return ans;
}
int main()
{
int T,n,tot;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
tot = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d%d",&l[i],&r[i]);
x[tot++] = l[i];
x[tot++] = r[i];
}
sort(x,x+tot);
tot = unique(x,x+tot)-x;
int all=1;
for(int i = 0;i < tot;i++)
{
has[x[i]] = all;
if(i < tot - 1)
{
if(x[i+1] - x[i] == 1)
all++;
else
all+=2;
}
}
build(1,1,all);
int num = 0;
for(int i = n;i >=1;i--)
{
if(insert(1,1,all,has[l[i]],has[r[i]]))
num ++;
}
printf("%d\n",num);
}
return 0;
}

浙公网安备 33010602011771号