POJ2777(Count Color)

经典的线段树的题,线段染色问题。跟“Mayor's Posters”那题差不多,只不过这题有多次查询。

需要注意的是给的区间[a,b],a可能会大于b。

View Code
#include <stdio.h>

#include <string.h>

#define N 100001

int n,m,k,ans;

int vis[31];

int color[4*N];

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

{

    int ls=cur<<1,rs=cur<<1|1;

    if(color[cur])

    {

        color[ls]=color[rs]=color[cur];

        color[cur]=0;

    }

}

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

{

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

    color[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 c)

{

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

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

    {

        color[cur]=c;

        return;

    }

    pushdown(cur,x,y);

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

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

}

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

{

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

    if(color[cur])

    {

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

        {

            vis[color[cur]]=1;

            return 1;

        }

        return 0;

    }

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

}

void query(int cur,int x,int y,int s,int t)

{

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

    if(color[cur])    //少了此处会TLE

    {

        if(vis[color[cur]]==0)  ans++;

        vis[color[cur]]=1;

        return;

    }

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

    {

        ans+=get(cur,x,y);

        return;

    }

    pushdown(cur,x,y);

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

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

}

int main()

{

    freopen("in.txt","r",stdin);

    int x,y,z;

    char c;

    while(~scanf("%d%d%d",&n,&k,&m))

    {

        build(1,1,n);

        color[1]=1;

        while(m--)

        {

            c=0;

            while(c!='C' && c!='P') scanf("%c",&c);

            scanf("%d%d",&x,&y);

            if(x>y)

            {

                int tmp=x;

                x=y,y=tmp;

            }

            if(c=='P')

            {

                memset(vis,0,sizeof(vis));

                ans=0;

                query(1,1,n,x,y);

                printf("%d\n",ans);

            }

            else

            {

                scanf("%d",&z);

                change(1,1,n,x,y,z);

            }

        }

    }

    return 0;

}

你可能感兴趣的:(count)