zoukankan      html  css  js  c++  java
  • POJ 2777 Count Color (线段树成段更新+二进制思维)

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

    题意是有L个单位长的画板,T种颜色,O个操作。画板初始化为颜色1。操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的颜色有几种。

    很明显的线段树成段更新,但是查询却不好弄。经过提醒,发现颜色的种类最多不超过30种,所以我们用二进制的思维解决这个问题,颜色1可以用二进制的1表示,同理,颜色2用二进制的10表示,3用100,...。假设有一个区间有颜色2和颜色3,那么区间的值为二进制的110(十进制为6)。那我们就把一个区间的颜色种类表示为(左孩子的值‘|’右孩子的值)。

    然后就是一个线段树的成段更新。

    有个坑点是这个题目的l可能比r大...

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 using namespace std;
      5 const int MAXN = 275000;
      6 struct segtree {
      7     int l , r , val , lazy;
      8 }T[MAXN << 3];
      9 //获取颜色的种类
     10 int get(int n) {
     11     int cont = 0;
     12     while(n) {
     13         if(n & 1) 
     14             cont++;
     15         n >>= 1;
     16     }
     17     return cont;
     18 }
     19 
     20 void init(int p , int l , int r) {
     21     int mid = (l + r) >> 1;
     22     T[p].l = l , T[p].r = r , T[p].lazy = 0;
     23     if(l == r) {
     24         T[p].val = 1;
     25         return ;
     26     }
     27     init(p << 1 , l , mid);
     28     init((p << 1)|1 , mid + 1 , r);
     29     T[p].val = (T[p << 1].val | T[(p << 1)|1].val);
     30 }
     31 
     32 void updata(int p , int l , int r , int val) {
     33     int mid = (T[p].l + T[p].r) >> 1;
     34     if(l == T[p].l && T[p].r == r) {
     35         T[p].val = val;
     36         T[p].lazy = val;
     37         return ;
     38     }
     39     if(T[p].lazy) {
     40         T[p << 1].val = T[(p << 1)|1].val = T[p].lazy;
     41         T[p << 1].lazy = T[(p << 1)|1].lazy = T[p].lazy;
     42         T[p].lazy = 0;
     43     }
     44     if(r <= mid) {
     45         updata(p << 1 , l , r , val);
     46     }
     47     else if(l > mid) {
     48         updata((p << 1)|1 , l , r , val);
     49     }
     50     else {
     51         updata(p << 1 , l , mid , val);
     52         updata((p << 1)|1 , mid + 1 , r , val);
     53     }
     54     T[p].val = (T[p << 1].val | T[(p << 1)|1].val);
     55 }
     56 //返回颜色种类的二进制对应的十进制的值
     57 int query(int p , int l , int r) {
     58     int mid = (T[p].l + T[p].r) >> 1;
     59     if(T[p].l == l && T[p].r == r) {
     60         return T[p].val;
     61     }
     62     if(T[p].lazy) {
     63         T[p << 1].val = T[(p << 1)|1].val = T[p].lazy;
     64         T[p << 1].lazy = T[(p << 1)|1].lazy = T[p].lazy;
     65         T[p].lazy = 0;
     66     }
     67     if(r <= mid) {
     68         return query(p << 1 , l , r);
     69     }
     70     else if(l > mid) {
     71         return query((p << 1)|1 , l , r);
     72     }
     73     else {
     74         return query(p << 1 , l , mid) | query((p << 1)|1 , mid + 1 , r);
     75     }
     76 }
     77 
     78 int main()
     79 {
     80     int L , t , n , l , r , c;
     81     char str[5];
     82     while(~scanf("%d %d %d" , &L , &t , &n)) {
     83         init(1 , 1 , L);
     84         while(n--) {
     85             scanf("%s" , str);
     86             if(str[0] == 'C') {
     87                 scanf("%d %d %d" , &l , &r , &c);
     88                 int temp = l + r;
     89                 l = min(l , r);
     90                 r = temp - l;
     91                 updata(1 , l , r , (1 << (c - 1)));
     92             }
     93             else {
     94                 scanf("%d %d" , &l , &r);
     95                 int temp = l + r;
     96                 l = min(l , r);
     97                 r = temp - l;
     98                 int res = get(query(1 , l , r));
     99                 printf("%d
    " , res);
    100             }
    101         }
    102     }
    103 }
  • 相关阅读:
    JavaScript经典语录
    ERP部门的添加(十一)
    List<T>Contains, Exists, Any之间的优缺点对比
    LINQ学习之旅(六)
    ERP仓库管理系统查询(十)
    MVC中Asp.Net管道(二)
    appfog 添加数据库支持
    appfog 使用
    java.util.ResourceBundle 读取国际化资源或配置文件
    Java 如何中断和恢复线程的执行
  • 原文地址:https://www.cnblogs.com/Recoder/p/5357170.html
Copyright © 2011-2022 走看看