zoukankan      html  css  js  c++  java
  • 【洛谷P1558】色板游戏

    线段树+状压

    在线段树上维护一个值表示这个区间的颜色,具体地讲,我们将这个区间的颜色进行状压,第1种颜色对应状压后的第1位,以此类推。这样我们维护的这个数就是状压之后的数,在合并区间时将两个数按位或即可,区间取值直接覆盖即可,最后我们统计答案时只需统计这个数有多少个1即可。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 typedef long long ll;
     7 int sum[100010<<2],tag[100010<<2],n,m,t;
     8 inline int read() {
     9     int ret=0;
    10     int op=1;
    11     char c=getchar();
    12     while(c<'0'||c>'9') {if(c=='-') op=-1; c=getchar();}
    13     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
    14     return ret*op;
    15 }
    16 inline void pushup(int now) {
    17     sum[now]=sum[now<<1]|sum[now<<1|1];
    18 }
    19 inline void pushdown(int now) {
    20     if(tag[now]) {
    21         tag[now<<1]=tag[now<<1|1]=tag[now];
    22         sum[now<<1]=sum[now<<1|1]=1<<tag[now];
    23         tag[now]=0;
    24     }
    25 }
    26 inline void build(int now,int l,int r) {
    27     if(l==r) {
    28         sum[now]=1<<1;
    29         return ;
    30     }
    31     int mid=l+r>>1;
    32     build(now<<1,l,mid);
    33     build(now<<1|1,mid+1,r);
    34     pushup(now);
    35 }
    36 void updata(int now,int l,int r,int x,int y,int val) {
    37     if(x<=l&&r<=y) {
    38         tag[now]=val;
    39         sum[now]=1<<val;
    40         return ;
    41     }
    42     pushdown(now);
    43     int mid=l+r>>1;
    44     if(x<=mid) updata(now<<1,l,mid,x,y,val);
    45     if(y>mid) updata(now<<1|1,mid+1,r,x,y,val);
    46     pushup(now);
    47 }
    48 int query(int now,int l,int r,int x,int y) {
    49     if(x<=l&&r<=y) return sum[now];
    50     pushdown(now);
    51     int mid=l+r>>1;
    52     int ret=0;
    53     if(x<=mid) ret|=query(now<<1,l,mid,x,y);
    54     if(y>mid) ret|=query(now<<1|1,mid+1,r,x,y);
    55     return ret;
    56 }
    57 int main() {
    58     n=read(); m=read(); t=read();
    59     build(1,1,n);
    60     while(t--) {
    61         int x,y,z;
    62         char op;
    63         cin>>op>>x>>y;
    64         if(op=='C') {
    65             cin>>z;
    66             if(x>y) swap(x,y);
    67             updata(1,1,n,x,y,z);
    68         }
    69         else {
    70             if(x>y) swap(x,y);
    71             int ret=query(1,1,n,x,y);
    72             int ans=0;
    73             for(int i=1;i<=m;i++)
    74                 if(ret&(1<<i)) ans++;
    75             printf("%d
    ",ans);
    76         }
    77     }
    78     return 0;
    79 }
    AC Code
  • 相关阅读:
    二分图最大匹配的K&#246;nig定理及其证明
    HDOJ 2389 Rain on your Parade
    HDOJ 1083 Courses
    HDOJ 2063 过山车
    POJ 1469 COURSES
    UESTC 1817 Complete Building the Houses
    POJ 3464 ACM Computer Factory
    POJ 1459 Power Network
    HDOJ 1532 Drainage Ditches
    HDU 1017 A Mathematical Curiosity
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10925389.html
Copyright © 2011-2022 走看看