题意:给一个长度非常长的墙上贴长度为ai的海报,由于有的会覆盖掉,求最后能看见的海报个数。
分析:题目和POJ2777 一模一样,方法也一样,只不过这个要离散化,其次要数组开大一点。至少2倍。
离散化的时候用了C++的 pair 类,还是比较好用的。
代码:
#include <iostream>
#include <algorithm>
#include <utility>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 25000;
pair<int,int> p[2*N];
pair<int,int> v[N];
int n;
int comp(pair<int,int> a,pair<int,int> b)
{
if(a.first!=b.first)
return a.first<b.first;
}
int cmp(pair<int,int> a,pair<int,int> b)
{
if(a.second!=b.second)
return a.second<b.second;
if(a.first!=b.first)
return a.first<b.first;
}
int Discrete() //离散化
{
for(int i=0; i<n; i++)
{
int x,y;
scanf("%d%d",&x,&y);
p[i*2]=make_pair(x,i);
p[i*2+1]=make_pair(y,i);
}
sort(p,p+2*n,comp);
int cnt=2,tmp=p[0].first;
p[0].first=1;
for(int i=1; i<n*2; i++)
{
if(p[i].first==tmp)
{
tmp=p[i].first;
p[i].first=(cnt-1);
}
else
{
tmp=p[i].first;
p[i].first=cnt++;
}
}
sort(p,p+2*n,cmp);
for(int i=0; i<2*n; i+=2)
v[i/2]=make_pair(p[i].first,p[i+1].first);
cnt--;
return cnt;
}
struct Node
{
int l,r;
long long num;
};
Node tree[4*N];
int vis[N*2];
void build(int l,int r,int o)
{
tree[o].l=l;
tree[o].r=r;
tree[o].num=1;
if(l==r)
return ;
int mid=(l+r)/2;
build(l,mid,o*2);
build(mid+1,r,o*2+1);
}
void update(int l,int r,int t,int o)
{
if(tree[o].l==l && tree[o].r==r)
{
tree[o].num=t;
return;
}
if(tree[o].num==t) return;
if(tree[o].num!=-1)
{
tree[2*o].num=tree[o].num;
tree[2*o+1].num=tree[o].num;
tree[o].num=-1;
}
int mid=(tree[o].l+tree[o].r)>>1;
if(r<=mid)
update(l,r,t,o+o);
else if(l>mid)
update(l,r,t,o+o+1);
else
{
update(l,mid,t,o*2);
update(mid+1,r,t,o*2+1);
}
}
void query(int l,int r,int o)
{
if(tree[o].num!=-1)
{
vis[tree[o].num]=1;
return ;
}
int mid=(tree[o].l+tree[o].r)>>1;
if(r<=mid)
query(l,r,o+o);
else if(l>mid)
query(l,r,o+o+1);
else
{
query(l,mid,o*2);
query(mid+1,r,o*2+1);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int cnt=Discrete();
build(1,cnt,1);
for(int i=0;i<n;i++)
{
update(v[i].first,v[i].second,i,1);
}
memset(vis,0,sizeof(vis));
query(1,cnt,1);
int ans=0;
for(int i=0;i<=cnt;i++)
if(vis[i]){
//printf("--%d ",i);
ans++;
}
printf("%d\n",ans);
memset(p,0,sizeof(p));
memset(v,0,sizeof(v));
}
return 0;
}