zoukankan      html  css  js  c++  java
  • poj2777Count Color——线段树+状压

    题目:http://poj.org/problem?id=2777

    状压每个颜色的选择情况,取答案时 | 一番;

    注意题目中的区间端点可能大小相反,在读入时换一下位置;

    注意pushdown()中要lazy标签不为0才进行更新。

    代码如下:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int const N=2000005;
    int t[N],lazy[N],len,tt,o;
    char dc;
    void pushdown(int x)
    {
        if(lazy[x])//!
        {
            lazy[x*2]=lazy[x];
            lazy[x*2+1]=lazy[x];
            t[x*2]=lazy[x];
            t[x*2+1]=lazy[x];
            lazy[x]=0;
        }
    }
    void pushup(int x)
    {
        t[x]=(t[x*2]|t[x*2+1]);
    }
    void build(int l,int r,int x)
    {
        t[x]=1;
        if(l==r)return;
        int mid=(l+r)/2;
        build(l,mid,x*2);
        build(mid+1,r,x*2+1);
    }
    void update(int l,int r,int ll,int rr,int s,int x)
    {
        if(l>=ll&&r<=rr)
        {
            t[x]=s;
            lazy[x]=s;
            return;
        }
        pushdown(x);
        int mid=(l+r)/2;
        if(mid>=ll)update(l,mid,ll,rr,s,x*2);
        if(mid<rr)update(mid+1,r,ll,rr,s,x*2+1);
        pushup(x);
    }
    int query(int l,int r,int ll,int rr,int x)
    {
        int ans=0;
        if(l>=ll&&r<=rr)
            return t[x];
        pushdown(x);
        int mid=(l+r)/2;
        if(mid>=ll)ans|=query(l,mid,ll,rr,x*2);
        if(mid<rr)ans|=query(mid+1,r,ll,rr,x*2+1);
        return ans;
    }
    int main()
    {
        while(scanf("%d%d%d",&len,&tt,&o)==3)
        {
            build(1,len,1);
            while(o--)
            {
                cin>>dc;
        //        printf("(%c)
    ",dc);
                if(dc=='C')
                {
                    int x,y,z;
                    scanf("%d%d%d",&x,&y,&z);
                    if(x>y)swap(x,y);
                    z=(1<<(z-1));
                    update(1,len,x,y,z,1);
                }
                if(dc=='P')
                {
                    int x,y;
                    scanf("%d%d",&x,&y);
                    if(x>y)swap(x,y);
                    int k=query(1,len,x,y,1);
                    int ans=0;
                    for(int i=1;i<=tt;i++)
                        if(k&(1<<(i-1)))ans++;
                    printf("%d
    ",ans);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    分页控件(后台拼接html方式)
    精子发生过程
    FSH 促卵泡激素
    LH 黄体生成素
    linux常用命令
    [C#]使用RabbitMQ模拟抽奖系统的例子
    自己写的一个关于Linq to Entity 动态查询的例子
    [C#]记一次解析XML转对象的笔记
    初次使用C#中的yield
    OI回忆录
  • 原文地址:https://www.cnblogs.com/Zinn/p/8721329.html
Copyright © 2011-2022 走看看