zoukankan      html  css  js  c++  java
  • 洛谷 1558 色板游戏

    【题解】

      容易想到用线段树维护,但是无脑开T棵线段树会导致时间超限。怎么办呢?我们可以把一个区间的状态用30位2进制数表示。第$i$位为$1$表示这个区间有第$i$种颜色,为$0$表示没有。

      这样我们只需要维护区间或的结果,并支持区间设为一个数即可。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define ls (u<<1)
     4 #define rs (u<<1|1)
     5 #define mid ((a[u].l+a[u].r)>>1)
     6 using namespace std;
     7 int n,m,c,l,r,col,exp[100];
     8 struct tree{
     9     int l,r,sum,same;
    10 }a[400010];
    11 inline int read(){
    12     int k=0,f=1; char c=getchar();
    13     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    14     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    15     return k*f;
    16 }
    17 void build(int u,int l,int r){
    18     a[u].l=l; a[u].r=r; a[u].sum=1; a[u].same=0;
    19     if(l<r) build(ls,l,mid),build(rs,mid+1,r);
    20 }
    21 void pushup(int u){a[u].sum=a[ls].sum|a[rs].sum;}
    22 void pushdown(int u){
    23     if(!a[u].same) return; a[u].same=0;
    24     a[ls].same=a[rs].same=1;
    25     a[ls].sum=a[rs].sum=a[u].sum;
    26 }
    27 void setsame(int u,int l,int r,int c){
    28     if(l<=a[u].l&&a[u].r<=r){
    29         a[u].same=1; a[u].sum=exp[c]; return;
    30     }
    31     pushdown(u);
    32     if(l<=mid) setsame(ls,l,r,c);
    33     if(r>mid) setsame(rs,l,r,c);
    34     pushup(u);
    35 }
    36 int query(int u,int l,int r){
    37     if(l<=a[u].l&&a[u].r<=r) return a[u].sum;
    38     pushdown(u); int ret=0;
    39     if(l<=mid) ret=query(ls,l,r);
    40     if(r>mid) ret=ret|query(rs,l,r);
    41     return ret;
    42 }
    43 int main(){
    44     n=read(); c=read(); m=read(); build(1,1,n);
    45     exp[1]=1;
    46     for(int i=2;i<=c;i++) exp[i]=exp[i-1]<<1;
    47     //for(int i=1;i<=c;i++) printf("%d ",exp[i]); puts("");
    48     while(m--){
    49         char ch=getchar();
    50         while(ch!='P'&&ch!='C') ch=getchar();
    51         if(ch=='C'){
    52             l=read(); r=read(); col=read();
    53             if(l>r) swap(l,r);
    54             setsame(1,l,r,col);
    55         }
    56         else{
    57             l=read(); r=read();
    58             if(l>r) swap(l,r);
    59             int ans=0,tmp=query(1,l,r);
    60             //printf("tmp=%d ",tmp);
    61             for(int i=c;i>=1;i--) if(tmp>=exp[i]) ans++,tmp-=exp[i];
    62             printf("%d
    ",ans);
    63         }
    64     }
    65     return 0;
    66 }
    View Code
  • 相关阅读:
    一个简单的rest_framework demo
    linux 文本编辑 软件管理
    linux 底层 基础命令 路径信息
    linux 安装 配置网络 备份 快照
    简单学习Python之路1
    站点的rel="alternate"属性
    mongoose的save无效的问题
    css3动画:transition和animation
    《http权威指南》读书笔记18
    《http权威指南》读书笔记17
  • 原文地址:https://www.cnblogs.com/DriverLao/p/8328630.html
Copyright © 2011-2022 走看看