题型:线段树
描述:长为L的报栏上按顺序贴广告[a,b],统计不同的广告数。
思路:数据要离散化处理,然后区间的更新和统计。
离散化方法参考:
离散化代码参考:
// 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 ;
}