PKU 2528

题型:线段树

描述:长为L的报栏上按顺序贴广告[a,b],统计不同的广告数。

思路:数据要离散化处理,然后区间的更新和统计。

离散化方法参考:

matrix67

离散化代码参考:

笑风生

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
// 1408K 63MS
#include < stdio.h >
#include
< stdlib.h >
#include
< string .h >
#define NL 32768

struct Seg {
int l, r, no;
}t[NL
* 2 ];

struct Ban {
int s, e, no;
int s1, e1;
bool isLeft;
}b[
10001 ];

struct R {
int a, no;
bool isLeft;
}
ref [ 20001 ];

bool flg[ 10001 ];
int cnt;

int cmp( const void * a, const void * b)
{
return (( struct R * )a) -> a - (( struct R * )b) -> a;
}

void build( int l, int r, int k)
{
t[k].l
= l;
t[k].r
= r;
t[k].no
= - 1 ;
int md = (l + r) >> 1 , k0 = k << 1 ;
if (l + 1 < r) {
build(l, md, k0);
build(md, r, k0
+ 1 );
}
}

void mody( int l, int r, int no, int k)
{
if (t[k].l == l && t[k].r == r) {
t[k].no
= no;
return ;
}
int md = (t[k].l + t[k].r) >> 1 , k0 = k << 1 ;
if (t[k].no >= 0 ) {
t[k0].no
= t[k0 + 1 ].no = t[k].no;
t[k].no
= - 1 ;
}
if (r <= md)
mody(l, r, no, k0);
else if (l >= md)
mody(l, r, no, k0
+ 1 );
else {
mody(l, md, no, k0);
mody(md, r, no, k0
+ 1 );
}
}

void count( int l, int r, int k)
{
if (t[k].l == l && t[k].r == r && t[k].no >= 0 ) {
if ( ! flg[t[k].no]) {
flg[t[k].no]
= 1 ;
cnt
++ ;
}
return ;
}
int md = (t[k].l + t[k].r) >> 1 , k0 = k << 1 ;
if (r <= md)
count(l, r, k0);
else if (l >= md)
count(l, r, k0
+ 1 );
else {
count(l, md, k0);
count(md, r, k0
+ 1 );
}
}

int main()
{
int n, T;
int i, j;
// freopen("in.txt", "r", stdin);

scanf(
" %d " , & T);
while (T -- ) {
scanf(
" %d " , & n);
for (i = 0 , j = 0 ; i < n; i ++ ) {
scanf(
" %d%d " , & b[i].s, & b[i].e);
b[i].no
= i;
ref [j].a = b[i].s, ref [j].isLeft = true , ref [j ++ ].no = i;
ref [j].a = b[i].e, ref [j].isLeft = false , ref [j ++ ].no = i;
}
// 离散化
qsort( ref , j, sizeof ( ref [ 0 ]), cmp);
int p, m = 1 , rf = ref [ 0 ].a;
p
= ref [ 0 ].no;
if ( ref [ 0 ].isLeft) b[p].s1 = m;
else b[p].e1 = m;
for (i = 1 ; i < j; i ++ ) {
if (rf != ref [i].a) {
rf
= ref [i].a;
m
++ ;
}
p
= ref [i].no;
if ( ref [i].isLeft) b[p].s1 = m;
else b[p].e1 = m;
}
// end离散化
build( 1 , m + 1 , 1 );
for (i = 0 ; i < n; i ++ ) {
mody(b[i].s1, b[i].e1
+ 1 , b[i].no, 1 );
}
memset(flg,
0 , sizeof (flg));
cnt
= 0 ;
count(
1 , m + 1 , 1 );
printf(
" %d\n " , cnt);
}
return 0 ;
}

 

转载于:https://www.cnblogs.com/superbin/archive/2010/07/17/1779519.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值