POJ 2528 Mayor's posters(线段树染色问题+离散化)

时间:2023-12-24 08:05:13

http://poj.org/problem?id=2528

题意:

给出一面无限长的墙,现在往墙上依次贴海报,问最后还能看见多少张海报。

题意:
这道题目就相当于对x轴染色,然后计算出最后还能看见多少种颜色。

由于数据量是给定的,所以需要进行离散化。但是这道题目的话,不能简单的离散化,前后相差大于1的话需要额外的插一个数。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn = + ; int n;
int ans;
int col[maxn<<];
int vis[maxn<<];
int l_pos[maxn<<],r_pos[maxn<<];
int x[maxn<<]; void PushDown(int o)
{
if(col[o]!=-)
{
col[o<<]=col[o<<|]=col[o];
col[o]=-;
}
} void update(int L, int R, int l, int r, int ID, int o)
{
if(L<=l && R>=r)
{
col[o]=ID;
return;
}
PushDown(o);
int mid=(l+r)/;
if(L<=mid) update(L,R,l,mid,ID,o<<);
if(R>mid) update(L,R,mid+,r,ID,o<<|);
} void query(int L, int R, int l, int r, int o)
{
if(col[o]!=-)
{
if(vis[col[o]]==) //每种颜色统计一次
{
ans++;
vis[col[o]]=;
}
col[o]=-;
return;
}
if(l==r) return;
PushDown(o);
int mid=(l+r)/;
if(L<=mid) query(L,R,l,mid,o<<);
if(R>mid) query(L,R,mid+,r,o<<|);
} int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
memset(col,-,sizeof(col));
memset(vis,,sizeof(vis)); scanf("%d",&n);
int cnt=;
for(int i=;i<=n;i++)
{
scanf("%d%d",&l_pos[i],&r_pos[i]);
x[++cnt]=l_pos[i];
x[++cnt]=r_pos[i];
} sort(x+,x+cnt+);
int cntt=cnt;
for(int i=;i<=cntt;i++)
{
if(x[i]-x[i-]>) x[++cnt]=x[i-]+; //插点
}
//离散化
sort(x+,x+cnt+);
int num=unique(x+,x+cnt+)-(x+);
for(int i=;i<=n;i++)
{
l_pos[i]=lower_bound(x+,x+num+,l_pos[i])-(x+);
r_pos[i]=lower_bound(x+,x+num+,r_pos[i])-(x+);
update(l_pos[i],r_pos[i],,num,i,);
} ans=;
query(,num,,num,);
printf("%d\n",ans);
}
return ;
}