• POJ2777解题报告【线段树,二进制存储状态】


    题目地址:

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

    题目概述:

      给一块长度为L的板子,有两种操作,第一种将A到B刷成颜色C,第二种询问A到B一共有多少种颜色。颜色数小于等于30。

    大致思路:

      首先很容易发现线段树可以解决问题,不过怎么储存颜色呢?我们发现颜色总数很少,于是可以为2进制位来表示颜色,问题就可以很好地解决了。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <ctime>
    #include <map>
    #include <stack>
    #include <queue>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define sacnf scanf
    #define scnaf scanf
    #define maxn  100010
    #define maxm 26
    #define inf 1061109567
    #define Eps 0.00001
    const double PI=acos(-1.0);
    #define mod 7
    #define MAXNUM 10000
    void Swap(int &a,int &b) {int t=a;a=b;b=t;}
    int Abs(int x) {return (x<0)?-x:x;}
    typedef long long ll;
    typedef unsigned int uint;
    
    struct node
    {
        int Set_flag,color;
    } tree[maxn*3];
    
    int t,p2[32];
    
    void build_tree(int l,int r,int dir)
    {
        tree[dir].color=(1<<1);tree[dir].Set_flag=0;
        if(l==r) return;
        int m=(l+r)>>1;
        build_tree(l,m,dir*2);
        build_tree(m+1,r,dir*2+1);
    }
    
    void pushdown(int l,int r,int dir)
    {
        if(l!=r)
        {
            tree[dir*2].Set_flag=tree[dir].Set_flag;
            tree[dir*2+1].Set_flag=tree[dir].Set_flag;
            tree[dir*2].color=tree[dir*2+1].color=(1<<tree[dir].Set_flag);
        }
        tree[dir].color=(1<<tree[dir].Set_flag);
        tree[dir].Set_flag=0;
    }
    
    void Set(int l,int r,int dir,int sl,int sr,int c)
    {
        if(sr<l||r<sl) return;
        if(sl<=l&&r<=sr)
        {
            tree[dir].Set_flag=c;
            tree[dir].color=(1<<c);
            return;
        }
        if(tree[dir].Set_flag!=0) pushdown(l,r,dir);
        int m=(l+r)>>1;
        Set(l,m,dir*2,sl,sr,c);
        Set(m+1,r,dir*2+1,sl,sr,c);
        tree[dir].color=(tree[dir*2].color|tree[dir*2+1].color);
    }
    
    int query(int l,int r,int dir,int ql,int qr)
    {
        if(qr<l||r<ql) return 0;
        if(tree[dir].Set_flag!=0) pushdown(l,r,dir);
        if(ql<=l&&r<=qr) return tree[dir].color;
        int m=(l+r)>>1,t1,t2;
        t1=query(l,m,dir*2,ql,qr);
        t2=query(m+1,r,dir*2+1,ql,qr);
        return (t1|t2);
    }
    
    void debug(int n)
    {
        for(int i=1;i<2*n;i++)
        {
            printf("%d ",tree[i].Set_flag);
            /*for(int j=1;j<=t;j++)
                if(tree[i].color[j]!=0) printf("%d,",j);
            printf("
    ");*/
        }
        printf("
    ");
    }
    
    int main()
    {
        //freopen("data.in","r",stdin);
        //freopen("data.out","w",stdout);
        //clock_t st=clock();
        int l,o;p2[0]=1;
        for(int i=1;i<=30;i++) p2[i]=p2[i-1]*2;
        while(~scanf("%d%d%d",&l,&t,&o))
        {
            build_tree(1,l,1);
            while(o--)
            {
                getchar();char c;int a,b,p;
                scanf("%c%d%d",&c,&a,&b);
                if(a>b) Swap(a,b);
                if(c=='C')
                {
                    scanf("%d",&p);
                    Set(1,l,1,a,b,p);
                }
                else if(c=='P')
                {
                    int ans=query(1,l,1,a,b);
                    int cnt=0;
                    for(int i=1;i<=t;i++)
                        if((ans&p2[i])==p2[i]) cnt++;
                    printf("%d
    ",cnt);
                }
                //debug(l);
            }
        }
        //clock_t ed=clock();
        //printf("
    
    Time Used : %.5lf Ms.
    ",(double)(ed-st)/CLOCKS_PER_SEC);
        return 0;
    }
  • 相关阅读:
    浅谈JS的数组遍历方法
    浅谈JavaScript函数重载
    随机数的组合问题(JavaScript描述)
    如何使用百度bae部署web项目
    阿里前端笔试总结
    有趣的JavaScript隐式类型转换
    CSS如何实现”右部宽度固定,左部自适应“的布局
    Nor Flash的理论性能
    python argparse:命令行参数解析详解
    rwcheck:为嵌入式设备设计的读写压测工具
  • 原文地址:https://www.cnblogs.com/CtrlKismet/p/6590598.html
Copyright © 2020-2023  润新知