zoukankan      html  css  js  c++  java
  • POJ 2777 Count Color

    POJ_2777

        这个题目在用线段树自顶向下处理的时候,需要对每个节点做两个标记,一个是当前区间包含的颜色,另一个就是lazy标记。

        lazy标记是为了节省更新子节点颜色的时间,也就是在染色时没有必要立刻更新子节点的颜色,而是在自顶向下查询时如果发现需要更新子节点,那么再将lazy标记不断下传并更新子节点,这样就节省了时间。

        对于颜色的表示,由于染色种类较少,因此可以用二进制数来表示每个区间的染色情况。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 100010
    int L, T, O, M, res, tree[4 * MAXD], left[4 * MAXD], right[4 * MAXD], lazy[4 * MAXD];
    char op[5];
    void init()
    {
    int i, j;
    for(M = 1; M < L + 2; M <<= 1);
    for(i = 0, j = M; i < M; i ++, j ++)
    left[j] = right[j] = i;
    for(i = M - 1; i > 0; i --)
    {
    left[i] = left[2 * i];
    right[i] = right[2 * i + 1];
    }
    for(i = 2 * M - 1; i > 0; i --)
    {
    tree[i] = (1 << 1);
    lazy[i] = 0;
    }
    }
    void paint(int cur, int a, int b, int col)
    {
    if(lazy[cur] && cur < M)
    {
    lazy[cur] = 0;
    lazy[2 * cur + 1] = lazy[2 * cur] = 1;
    tree[2 * cur + 1] = tree[2 * cur] = tree[cur];
    }
    if(left[cur] >= a && right[cur] <= b)
    {
    tree[cur] = (1 << col);
    lazy[cur] = 1;
    for(int i = cur; i ^ 1; i >>= 1)
    tree[i >> 1] = (tree[i] | tree[i ^ 1]);
    return ;
    }
    if(left[2 * cur] <= b && right[2 * cur] >= a)
    paint(2 * cur, a, b, col);
    if(left[2 * cur + 1] <= b && right[2 * cur + 1] >= a)
    paint(2 * cur + 1, a, b, col);
    }
    void search(int cur, int a, int b)
    {
    if(lazy[cur] && cur < M)
    {
    lazy[cur] = 0;
    lazy[2 * cur + 1] = lazy[2 * cur] = 1;
    tree[2 * cur + 1] = tree[2 * cur] = tree[cur];
    }
    if(right[cur] <= b && left[cur] >= a)
    {
    res |= tree[cur];
    return ;
    }
    if(left[2 * cur] <= b && right[2 * cur] >= a)
    search(2 * cur, a, b);
    if(left[2 * cur + 1] <= b && right[2 * cur + 1] >= a)
    search(2 * cur + 1, a, b);
    }
    void solve()
    {
    int i, j, k, A, B, C, num;
    scanf("%s", op);
    if(op[0] == 'C')
    {
    scanf("%d%d%d", &A, &B, &C);
    if(A > B)
    {
    k = A;
    A = B;
    B = k;
    }
    paint(1, A, B, C);
    }
    else
    {
    scanf("%d%d", &A, &B);
    if(A > B)
    {
    k = A;
    A = B;
    B = k;
    }
    res = 0;
    search(1, A, B);
    num = 0;
    for(i = 1; i <= 30; i ++)
    if(res & (1 << i))
    num ++;
    printf("%d\n", num);
    }
    }
    int main()
    {
    while(scanf("%d%d%d", &L, &T, &O) == 3)
    {
    init();
    for(int i = 0; i < O; i ++)
    solve();
    }
    return 0;
    }


  • 相关阅读:
    html5+css3酷炫音频播放器代码
    js/html/css做一个简单的图片自动(auto)轮播效果//带注释
    gVIM+zencoding快速开发HTML/CSS/JS(适用WEB前端)
    使用libcurl,根据url下载对应html页面
    CSS+HTML+JQuery简单菜单
    【POJ1845】Sumdiv(数论/约数和定理/等比数列二分求和)
    【CodeForces727E/CF727E】Games on a CD (字符串哈希)
    【洛谷3224/BZOJ2733】[HNOI2012]永无乡 (Splay启发式合并)
    【BZOJ2565】最长双回文串 (Manacher算法)
    【洛谷2926/BZOJ1607】[USACO08DEC]Patting Heads拍头(筛法)
  • 原文地址:https://www.cnblogs.com/staginner/p/2230647.html
Copyright © 2011-2022 走看看