• POJ 2777 Count Color 线段树


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

    虽然是简单题,但是我还是写一下我的理解。

    插入和查询都是自上而下进行的,所以如果当前线段是红色的,那么子节点肯定也是红色的,不必继续往下遍历,这便是lazy的核心。

    所以我们要标记一段线段是否是纯色的,这个题颜色用1-30来表示,所以我用0表示非纯色,非纯色时要继续遍历子节点。

    当需要插入当前线段的子线段时,如果当前线段是纯色的,先把当前线段的颜色赋给左右子线段,然后标记当前线段为非纯色(即0),然后继续递归插入子线段,这样就成功降低了时间复杂度。

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <algorithm>
      4 
      5 const int MAXN = 100010;
      6 bool flag[35];
      7 
      8 struct Tree_Node
      9 {
     10     int left, right;
     11     int color;
     12 } tree[MAXN<<2];
     13 
     14 void build(int left, int right, int step)
     15 {
     16     tree[step].left = left;
     17     tree[step].right = right;
     18     tree[step].color = 1;
     19     if(left == right)
     20     {
     21         return;
     22     }
     23     int mid = (left + right) >> 1;
     24     build(left, mid, step<<1);
     25     build(mid+1, right, step<<1|1);
     26 }
     27 
     28 void insert(int left, int right, int color, int step)
     29 {
     30     int mid = (tree[step].left + tree[step].right) >> 1;
     31     if(tree[step].left == left && tree[step].right == right)
     32     {
     33         tree[step].color = color;
     34         return;
     35     }
     36     if(tree[step].color == color)
     37         return;
     38     if(tree[step].color > 0)
     39     {
     40         tree[step<<1].color = tree[step<<1|1].color = tree[step].color;
     41         tree[step].color = 0;
     42     }
     43     if(right <= mid)
     44     {
     45         insert(left, right, color, step<<1);
     46     }
     47     else if(left > mid)
     48     {
     49         insert(left, right, color, step<<1|1);
     50     }
     51     else
     52     {
     53         insert(left, mid, color, step<<1);
     54         insert(mid+1, right, color, step<<1|1);
     55     }
     56 }
     57 
     58 void query(int left, int right, int step)
     59 {
     60     int mid = (tree[step].left + tree[step].right) >> 1;
     61     if(tree[step].color > 0)
     62     {
     63         flag[tree[step].color] = 1;
     64         return;
     65     }
     66     if(right <= mid)
     67     {
     68         query(left, right, step<<1);
     69     }
     70     else if(left > mid)
     71     {
     72         query(left, right, step<<1|1);
     73     }
     74     else
     75     {
     76         query(left, mid, step<<1);
     77         query(mid+1, right, step<<1|1);
     78     }
     79 }
     80 
     81 int main()
     82 {
     83     int l, m, n;
     84     int left, right, color;
     85     char cmd[2];
     86     scanf("%d %d %d", &l, &m, &n);
     87     build(1, l, 1);
     88     while(n--)
     89     {
     90         scanf("%s", cmd);
     91         if(cmd[0] == 'C')
     92         {
     93             scanf("%d %d %d", &left, &right, &color);
     94             if(left > right)
     95                 std::swap(left, right);
     96             insert(left, right, color, 1);
     97         }
     98         else
     99         {
    100             scanf("%d %d", &left, &right);
    101             if(left > right)
    102                 std::swap(left, right);
    103             memset(flag, 0, sizeof(flag));
    104             query(left, right, 1);
    105             int ans = 0;
    106             for(int i = 1; i <= m; i++)
    107             {
    108                 ans += flag[i];
    109             }
    110             printf("%d
    ", ans);
    111         }
    112     }
    113     return 0;
    114 }
    View Code
  • 相关阅读:
    sqlilabs 5
    sqlilabs 1-4
    ipset
    kill命令的使用
    docker 札记
    批量删除数据库表中数据行
    正则表达式调试
    TimescaleDB安装学习
    记一次 Centos7 postgresql v11 安装时序数据库 TimescaleDB
    "知识库"
  • 原文地址:https://www.cnblogs.com/wolfred7464/p/3409316.html
Copyright © 2020-2023  润新知