POJ 2528 Mayor's posters 离散化线段树
终于知道离散化是什么东西了.....
/******************************************
离散过程
(1-8) (1-3) (6-8)
出现了1 3 6 8
->1 2 3 4
海报即变为
(1-4) (1-2) (3-4)
******************************************/
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid (l+r)>>1
const int maxn=1000003;
int sum[maxn<<2];
int t,x[maxn],y[maxn],i,X[maxn<<2],flag[maxn<<2],ans;
void pushdown(int rt){
if(sum[rt]){
sum[rt<<1]=sum[rt<<1|1]=sum[rt];
sum[rt]=0;
}
}
void update(int L,int R,int num,int l,int r,int rt){
if(L<=l&&r<=R){
sum[rt]=num; //标记海报种类
return ;
}
pushdown(rt);//向下更新
int m=mid;
if(L<=m) update(L,R,num,lson);
if(m<R) update(L,R,num,rson);
}
void query(int l,int r,int rt){
if(l==r){
if(!flag[sum[rt]]&&sum[rt]!=0){
ans++;
flag[sum[rt]]=1;//数量+1 标记
}
return;
}
else if(sum[rt]){
if(!flag[sum[rt]]){
ans++;flag[sum[rt]]=1;//数量+1 标记
}
return;
}
int m=mid;
query(lson); query(rson);
}
int findx(int x,int n,int q[])//二分查找位置;
{
int l=1,r=n;
while(l<=r){
int m=(l+r)>>1;
if(x==X[m])
return m;
else if(x<X[m])
r=m-1;
else l=m+1;
}
return 0;
}
int main()
{
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
int num=1;
for(i=1;i<=n;i++){
scanf("%d%d",&x[i],&y[i]);
X[num++]=x[i];//起点
X[num++]=y[i];//终点
}
int r=1;
sort(X+1,X+num);
for(i=1;i<num;i++){
if(X[i]!=X[i+1])
X[r++]=X[i];//去重点
}
r--;//还剩下几个数
memset(sum,0,sizeof(sum));
for(i=1;i<=n;i++)
update(findx(x[i],r,X),findx(y[i],r,X),i,1,r,1);//findx(二分)找到海报 离散化后的位置
memset(flag,0,sizeof(flag));
ans=0;
query(1,r,1);
printf("%d\n",ans);
}
return 0;
}

浙公网安备 33010602011771号