poj 2528 Mayor's posters (线段树+离散化)

这是我做的的一道线段树题,虽然不完全是自己想出来的,但是收获依然很大,就从这道题开始我的线段树之旅吧!

这道题的意思是:在一面墙上张贴宣传画,可以覆盖按照给定的张贴的顺序,求张贴完所有的画后能够看见几张画。

由于题目中给出的数据范围很大,1~10000000,所以首先要离散化,然后在用线段树进行更新查找。

贴代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct node//记录画的位置,以便对输入点进行排序
{
int x;
int num;
}s[20004];
struct tree//建线段树
{
int l,r;
int color;
}p[100004];
int n,sum;
int m[10003][2];
int f[20004];//标记该点是否被覆盖

int cmp(const void *a,const void *b)
{
return (*(struct node *)a).num - (*(struct node *)b).num;
}

void built(int t,int lc,int rc)//建树
{
p[t].l=lc;
p[t].r=rc;
p[t].color=0;
if(lc==rc)return ;
built(2*t,lc,(lc+rc)/2);
built(2*t+1,(lc+rc)/2+1,rc);
}

void insert(int t,int lc,int rc,int col)//更新各点
{
if(p[t].l==lc&&p[t].r==rc)
{
p[t].color=col;
return ;
}
if(p[t].color>0&&p[t].color!=col)
{
p[2*t].color=p[2*t+1].color=p[t].color;
p[t].color=0;
}
int mid=(p[t].l+p[t].r)/2;
if(rc<=mid)
insert(2*t,lc,rc,col);
else if(lc>mid)
insert(2*t+1,lc,rc,col);
else
{
insert(2*t,lc,mid,col);
insert(2*t+1,mid+1,rc,col);
}
}

void search(int t)//查找
{
if(p[t].color!=0)
{
if(!f[p[t].color])
{
f[p[t].color]=1;
sum++;
}
return ;
}
search(2*t);
search(2*t+1);
}

int main()
{
int cas,i;

scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d%d",&m[i][0],&m[i][1]);
s[2*i].x=-(i+1);
s[2*i].num=m[i][0];
s[2*i+1].x=i+1;
s[2*i+1].num=m[i][1];
}
qsort(s,2*n,sizeof(s[0]),cmp);
int ss=1;
int tem=s[0].num;
for(i=0;i<2*n;i++)
{
if(s[i].num!=tem)
{
ss++;
tem=s[i].num;
}
if(s[i].x<0)
m[-s[i].x-1][0]=ss;
else
m[s[i].x-1][1]=ss;
}
built(1,1,ss);
for(i=0;i<n;i++)
insert(1,m[i][0],m[i][1],i+1);
memset(f,0,sizeof(f));
sum=0;
search(1);
printf("%d\n",sum);
}
return 0;
}



原文地址:https://www.cnblogs.com/misty1/p/2431014.html