zoukankan      html  css  js  c++  java
  • 【*篇】luogu1558&&poj2777 色板游戏

    题目の传送门:
    luogu:https://www.luogu.org/problem/show?pid=1558
    poj:http://poj.org/problem?id=2777

    题目大意:给有个长度为L的区间,支持区间染色和区间查询颜色数。

    非常水的线段树。一眼看出,然后30min AC(尽管我luogu上交了四遍)(我太辣鸡了orz)

    这里我们显然可以状态压缩。用(1 << x) 不过要记住初始颜色1的值要设为2(1<<1)就因为这个我WA了两遍。。(然后又因为线段树忘了开四倍RE了一遍)
    然后区间覆盖直接打标记覆盖就好,区间查询的话用到了神奇的or运算,把他们全or起来就是一个数了,然后统计这个数中1的个数即可。。
    统计1的时候,我的方法是不断xor lowbit,这样的效率要比一位一位扫快一丢丢(虽然并快不了多少)。。
    代码就是下面的query,自己看下就行了。。
    好吧,然后下面直接上代码即可,这真的是一道非常的线段树。。

    #include <cstdio>
    const int MAXN=400101;
    int t[MAXN],lz[MAXN];
    inline void swap(int &a,int &b)
    {
        int c=a;a=b;b=c;
    }
    inline int getnum()
    {
        int a=0;char c=getchar();bool f=0;
        for(;(c<'0'||c>'9')&&c!='-'&&c!='C'&&c!='P';c=getchar());
        if(c=='C') return -1;
        if(c=='P') return -2;
        if(c=='-') c=getchar(),f=1;
        for(;c>='0'&&c<='9';c=getchar()) a=(a<<1)+(a<<3)+c-'0';
        if(f) return -a; return a;
    }
    inline void update(int x)
    {
        t[x]=t[x<<1]|t[x<<1|1];
    }
    inline void pushdown(int x)
    {
        if(!lz[x]) return;
        t[x<<1]=lz[x<<1]=t[x<<1|1]=lz[x<<1|1]=lz[x];
        lz[x]=0;
    }
    void build(int x,int l,int r)
    {
        if(l==r)
        {
            t[x]=2;
            return;
        }
        int mid=(l+r)>>1;
        build(x<<1,l,mid);
        build(x<<1|1,mid+1,r);
        update(x);
    }
    void change(int x,int l,int r,int L,int R,int w)
    {
        if(L<=l&&r<=R)
        {
            t[x]=1<<w;
            lz[x]=1<<w;
            return;
        }
        pushdown(x);
        int mid=(l+r)>>1;
        if(L<=mid) change(x<<1,l,mid,L,R,w);
        if(R>mid) change(x<<1|1,mid+1,r,L,R,w);
        update(x);
    }
    int findans(int x,int l,int r,int L,int R)
    {
        int ans=0;
        if(L<=l&&r<=R) return t[x];
        pushdown(x);
        int mid=(l+r)>>1;
        if(L<=mid) ans|=findans(x<<1,l,mid,L,R);
        if(R>mid) ans|=findans(x<<1|1,mid+1,r,L,R);
        return ans;
    }
    int query(int ans)
    {
        int cnt=0;
        for(;ans;ans^=(ans&-ans)) cnt++;
        return cnt;
    }
    int main()
    {
        int n=getnum(),t=getnum(),m=getnum();
        build(1,1,n);
        while(m--)
        {
            int opt=getnum();
            if(opt==-1)
            {
                int a=getnum(),b=getnum(),c=getnum();
                if(a>b) swap(a,b);
                change(1,1,n,a,b,c);
            }
            else
            {
                int a=getnum(),b=getnum();
                if(a>b) swap(a,b);
                printf("%d
    ",query(findans(1,1,n,a,b)));
            }
        }
    }
  • 相关阅读:
    移动硬盘无法识别提示需要格式化的解决办法
    Cassandra 入门(资料收集)
    [转] NoSQL生态系统
    软件项目实施问题收集(LastUpdatedOn:20141117)
    Sql server 收缩日志
    关于重构需要了解的一些原则
    C#定时任务采用线程和队列实现
    [转]我是如何带领团队开发项目的
    ASP.NET MVC 多套皮肤解决方案
    Mysql 问题汇总(不断更新中...)
  • 原文地址:https://www.cnblogs.com/enzymii/p/8412141.html
Copyright © 2011-2022 走看看