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;
}
原文地址:https://www.cnblogs.com/algorithms/p/2589735.html