POJ2582(Mayor's Posters)

数学模型:给定一个整数序列(最多10000000个数),初始化为0,一共有n(最大10000)个操作,其中第i个操作是将某个指定区间内的数赋值为i,求在经过n次操作后,序列中有多少个不同的非0数

该题可用线段数来做,保存的关键信息为这段的值,最后的查询只有一次。

需要注意的是最多有10000000个数,但n不大,所以可以用离散化处理进行优化。

View Code
#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#define N 10001

#define INF 0x7fffffff

int a[N],b[N],c[2*N],top;

int vis[N];

int id[8*N];

int cmp(const void *a,const void *b)

{

    return (*(int*)a)-(*(int*)b);

}

int Search(int x)

{

    int mid,min=0,max=top;

    while(min+1!=max)

    {

        mid=(min+max)>>1;

        if(c[mid]>x)    max=mid;

        else    min=mid;

    }

    return min;

}

void pushdown(int cur,int x,int y)

{

    int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1;

    if(id[cur])

    {

        id[ls]=id[rs]=id[cur];

        id[cur]=0;

    }

}

void build(int cur,int x,int y)

{

    int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1;

    id[cur]=0;

    if(x==y)    return;

    build(ls,x,mid);

    build(rs,mid+1,y);

}

void change(int cur,int x,int y,int s,int t,int k)

{

    int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1;

    if(x>=s && y<=t)

    {

        id[cur]=k;

        return;

    }

    pushdown(cur,x,y);

    if(mid>=s)  change(ls,x,mid,s,t,k);

    if(mid+1<=t)    change(rs,mid+1,y,s,t,k);

}

int get(int cur,int x,int y)

{

    int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1;

    if(id[cur])

    {

        if(0==vis[id[cur]])

        {

            vis[id[cur]]=1;

            return 1;

        }

        return 0;

    }

    if(x==y)    return 0;

    return get(ls,x,mid)+get(rs,mid+1,y);

}

int main()

{

    int t,n,i;

    scanf("%d",&t);

    while(t--)

    {

        scanf("%d",&n);

        top=0;

        for(i=0;i<n;i++)

        {

            scanf("%d%d",&a[i],&b[i]);

            c[top++]=a[i];

            c[top++]=b[i];

        }

        qsort(c,top,sizeof(c[0]),cmp);

        top=1;

        for(i=1;c[i];i++)

        {

            if(c[i]!=c[top-1])  c[top++]=c[i];

        }

        c[top]=INF;

        build(1,0,top-1);

        for(i=0;i<n;i++)

        {

            a[i]=Search(a[i]);

            b[i]=Search(b[i]);

            change(1,1,top,a[i]+1,b[i]+1,i+1);

        }

        memset(vis,0,sizeof(vis[0])*(n+1));

        printf("%d\n",get(1,1,top));

    }

    return 0;

}

你可能感兴趣的:(post)