zoukankan      html  css  js  c++  java
  • COJ 0712 Can you answer these queries II

    ------------------------------------------------------------------------------------
    线段树的区间操作:修改区间内的值,反转区间内的值,区间查询;
    ------------------------------------------------------------------------------------

    Description

    维护一个只有0和1的整数序列,支持以下操作:
    1 x y v : 将区间[x,y]之间的所有整数都变为v(v为0或1);
    2 x y : 将区间[x,y]之间所有的1变为0,所有的0变为1;
    3 x y : 查询区间[x,y]内的1的个数。

    Input

    输入文件包含多组测试数据。
    对于每组测试数据,第一行为一个整数N(1<=N<=10^5),表示这个序列一共有N个整数。接下来一行有N个值为0或1的整数,分别描述了序列中的N个整数。再接下来一行有一个整数M(1<=M<=10^5),表示一共有M个操作。

    Output

    对于每个查询均用一行输出查询的结果。

    Sample Input

    4 0 0 1 0 6 3 1 4 2 1 4 3 1 4 1 1 2 0 1 3 3 1 3 1 4

    Sample Output

    1 3 2
    ------------------------------------------------------------------------------------
    # include <stdio.h>
    
    # define N 100015
    # define NON 0x7fffffff
    
    int n, m, num[N];
    int ones[4 * N], set[4 * N], rev[4 * N];
    
    void update(int r)
    {
        ones[r] = ones[r << 1] + ones[(r << 1) | 1];
    }
    
    void pushdown(int r, int x, int y)
    {
        int mid = (x+y) >> 1, ls = r << 1, rs = (r << 1) | 1;
    
        if (set[r] != NON)
        {
            rev[ls] = rev[rs] = 0;
            set[ls] = set[rs] = set[r], set[r] = NON;
            ones[ls] = (mid-x+1) * set[ls];
            ones[rs] = (y-mid) * set[rs];
        }
        if (rev[r])
        {
            rev[ls] ^= 1;
            rev[rs] ^= 1;
            ones[ls] = mid-x+1 - ones[ls];
            ones[rs] = y - mid - ones[rs];
            rev[r] = 0;    
        }
    }
    
    void build(int r, int x, int y)
    {
        set[r] = NON, rev[r] = 0;
        if (x == y)
        {
            ones[r] = num[x];
            return ;
        }
        int mid = (x + y) >> 1, ls = r << 1, rs = (r << 1) | 1;
        build(ls, x, mid);
        build(rs, mid+1, y);
        update(r);
    }
    
    void change(int r, int x, int y, int s, int t, int val)
    {
        if (s<=x && y<=t)
        {
            ones[r] = (y-x+1) * val;
            set[r] = val;
            rev[r] = 0;
            return ;
        }
        pushdown(r, x, y);
        int mid = (x+y) >> 1, ls = r << 1, rs = (r << 1) | 1;
        if (s <= mid) change(ls, x, mid, s, t, val);
        if (mid+1 <= t) change(rs, mid+1, y, s, t, val);
        update(r);
    }
    
    void flip(int r, int x, int y, int s, int t)
    {
        if (s<=x && y<=t)
        {
            rev[r] ^= 1;
            ones[r] = y-x+1 - ones[r];
            return ;
        }
        pushdown(r, x, y);
        int mid = (x+y) >> 1, ls = r << 1, rs = (r << 1) | 1;
        if (s <= mid) flip(ls, x, mid, s, t);
        if (mid+1 <= t) flip(rs, mid+1, y, s, t);
        update(r);
    }
    
    void query(int r, int x, int y, int s, int t, int &ans)
    {
        if (s<=x && y<=t)
        {
            ans += ones[r];
            return ;
        }
        pushdown(r, x, y);
        int mid = (x+y) >> 1, ls = r << 1, rs = (r << 1) | 1;
        if (s <= mid) query(ls, x, mid, s, t, ans);
        if (mid+1 <= t) query(rs, mid+1, y, s, t, ans);
    }
    
    void init(void)
    {
        for (int i = 1; i <= n; ++i)
        {
            scanf("%d", &num[i]);
        }
        scanf("%d", &m);
        build(1, 1, n);
    }
    
    void solve(void)
    {
        int id, val, s, t, ans;
    
        for (int i = 1; i <= m; ++i)
        {
            scanf("%d", &id);
            switch(id)
            {
            case 1: {scanf("%d%d%d", &s, &t, &val); change(1, 1, n, s, t, val); break;}
            case 2: {scanf("%d%d", &s, &t); flip(1, 1, n, s, t); break;}
            case 3: {scanf("%d%d", &s, &t); ans = 0; query(1, 1, n, s, t, ans); printf("%d\n", ans); break;}
            }
        }
    
        return ;
    }
    
    int main()
    {
        while (~scanf("%d", &n))
        {
            init();
            solve();
        }
    
        return 0;
    }
    ------------------------------------------------------------------------------------
  • 相关阅读:
    ihaiLjEUSx
    表达式的逆波兰式转化模板
    运算表达式求值模板
    程序员花式拜年脚本
    vbs脚本实现自动打字祝福&搞笑
    MFC实现红黑砖块
    vbs脚本实现qq定时发消息(初级)
    打包java程序生成exe
    webpack配置
    vue路由
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2587988.html
Copyright © 2011-2022 走看看