BZOJ5029: 贴小广告

Posted Star_Feel

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ5029: 贴小广告相关的知识,希望对你有一定的参考价值。

【传送门:BZOJ5029


简要题意:

  给出m段区间l[i],r[i],表示l[i]到r[i]的数全部变成i,求出最后有多少种不同的数


题解:

  线段树+离散化

  这是一道经典例题

  先离散化l和r

  然后线段树维护区间颜色就行了


参考代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct trnode
{
    int l,r,lc,rc,c;
}tr[210000];int len;
void bt(int l,int r)
{
    len++;int now=len;
    tr[now].l=l;tr[now].r=r;tr[now].c=-1;
    tr[now].lc=tr[now].rc=-1;
    if(l<r)
    {
        int mid=(l+r)/2;
        tr[now].lc=len+1;bt(l,mid);
        tr[now].rc=len+1,bt(mid+1,r);
    }
}
bool v[210000];
void wen(int now,int l,int r)
{
    if(tr[now].c>0)
    {
        v[tr[now].c]=true;
        return ;
    }
    int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
    if(r<=mid) wen(lc,l,r);
    else if(l>mid) wen(rc,l,r);
    else
    {
        wen(lc,l,mid);
        wen(rc,mid+1,r);
    }
}
void change(int now,int l,int r,int k)
{
    if(tr[now].c==k) return ;
    if(l==tr[now].l&&r==tr[now].r)
    {
        tr[now].c=k;
        return ;
    }
    int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
    if(tr[now].c>0)
    {
        tr[lc].c=tr[now].c;
        tr[rc].c=tr[now].c;
    }
    if(r<=mid) change(lc,l,r,k);
    else if(mid<l) change(rc,l,r,k);
    else
    {
        change(lc,l,mid,k);
        change(rc,mid+1,r,k);
    }
    if(tr[lc].c==tr[rc].c&&tr[lc].c>0) tr[now].c=tr[lc].c;
    else tr[now].c=-1;
}
struct LSnode
{
    int x,p,z;
}A[210000],B[210000];
int cmp(const void *x1,const void *x2)
{
    LSnode n1=*(LSnode *)x1;
    LSnode n2=*(LSnode *)x2;
    return n1.x-n2.x;
}
int main()
{
    int m;
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&A[2*i-1].x,&A[2*i].x);
        A[2*i-1].p=2*i-1;
        A[2*i].p=2*i;
    }
    for(int i=1;i<=2*m;i++)
    {
        B[i].x=A[i].x;
        B[i].p=A[i].p;
    }
    qsort(B+1,2*m,sizeof(LSnode),cmp);
    B[1].z=1;
    for(int i=2;i<=2*m;i++)
    {
        if(B[i].x==B[i-1].x) B[i].z=B[i-1].z;
        else B[i].z=B[i-1].z+1;
    }
    for(int i=1;i<=2*m;i++) A[B[i].p].z=B[i].z;
    len=0;bt(1,B[2*m].z);tr[1].c=0;
    for(int i=1;i<=m;i++) change(1,A[2*i-1].z,A[2*i].z,i);
    memset(v,false,sizeof(v));
    wen(1,1,B[2*m].z);
    int ans=0;
    for(int i=1;i<=m;i++) if(v[i]==true) ans++;
    printf("%d\n",ans);
    return 0;
}

 

以上是关于BZOJ5029: 贴小广告的主要内容,如果未能解决你的问题,请参考以下文章

用jQuery动态添加小广告

用html怎么做上下滚动的文字或者图片(就跟那种小广告一样~)

JS淘宝小广告

[数据集][VOC]张贴小广告数据集voc格式1725张

bzoj5029 Relief grain

R语言_001向量