zoj 1610 Count the Colors(线段树染色)

来源:互联网 发布:网络宣传平台有哪些 编辑:程序博客网 时间:2024/05/04 12:38

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1610

思路:线段树区间染色,线段树查询时用color记录左边的颜色,如果和左边颜色一样那么就不属于新的一段,注意最后一个color的记录,要单独记录到ans中。数据读入中xa不代表区间,而是一个点,这样xa,xb之间的区间其实就是区间[xa+1,xb]。

#include<cstdio>#include<cstring>using namespace std;const int N=8005;struct node{    int l,r,f,c;}d[N<<2];int color,ans[N],cnt;int max(int a,int b){    if(a>b)        return a;    return b;}void pushdown(int rt){    if(d[rt].l==d[rt].r)        return ;    d[rt].f=1;    d[rt<<1].f=d[rt<<1|1].f=0;    d[rt<<1].c=d[rt<<1|1].c=d[rt].c;}void pushup(int rt){    if(d[rt].l==d[rt].r)        return ;    if(d[rt<<1].f==0&&d[rt<<1|1].f==0&&d[rt<<1].c==d[rt<<1|1].c)    {        d[rt].f=0;        d[rt].c=d[rt<<1].c;    }}void build(int rt,int L,int R){    d[rt].l=L;    d[rt].r=R;    d[rt].f=0;    d[rt].c=-1;    if(L==R)        return ;    int mid=(L+R)>>1;    build(rt<<1,L,mid);    build(rt<<1|1,mid+1,R);}void updata(int rt,int L,int R,int col){    if(d[rt].l==L&&d[rt].r==R)    {        d[rt].f=0;        d[rt].c=col;        return ;    }    if(d[rt].f==0)        pushdown(rt);    int mid=(d[rt].l+d[rt].r)>>1;    if(R<=mid)        updata(rt<<1,L,R,col);    else if(L>mid)        updata(rt<<1|1,L,R,col);    else    {        updata(rt<<1,L,mid,col);        updata(rt<<1|1,mid+1,R,col);    }    pushup(rt);}void query(int rt,int L,int R){    if(d[rt].f==0)    {        if(d[rt].l==L&&d[rt].r==R)        {            if(d[rt].c!=color)            {                if(color>=0)                    ans[color]++;                color=d[rt].c;                if(color>cnt)                    cnt=color;            }            return ;        }        else            pushdown(rt);    }    int mid=(d[rt].l+d[rt].r)>>1;    if(R<=mid)        query(rt<<1,L,R);    else if(L>mid)        query(rt<<1|1,L,R);    else    {        query(rt<<1,L,mid);        query(rt<<1|1,mid+1,R);    }}int main(){    int n,a,b,c,i,mr;    freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    while(scanf("%d",&n)!=EOF)    {        build(1,0,8000);        mr=0;        while(n--)        {            scanf("%d%d%d",&a,&b,&c);            mr=max(mr,a);            mr=max(mr,b);            updata(1,a+1,b,c);        }        memset(ans,0,sizeof(ans));        color=-1;cnt=0;        query(1,1,mr);        if(color>=0)            ans[color]++;        for(i=0;i<=cnt;i++)            if(ans[i])                printf("%d %d\n",i,ans[i]);        printf("\n");    }    return 0;}



0 0
原创粉丝点击