• FZU Problem 2105 Digits Count


    Problem Description

    Given N integers A={A[0],A[1],...,A[N-1]}. Here we have some operations:

    Operation 1: AND opn L R

    Here opn, L and R are integers.

    For L≤i≤R, we do A[i]=A[i] AND opn (here "AND" is bitwise operation).

    Operation 2: OR opn L R

    Here opn, L and R are integers.

    For L≤i≤R, we do A[i]=A[i] OR opn (here "OR" is bitwise operation).

    Operation 3: XOR opn L R

    Here opn, L and R are integers.

    For L≤i≤R, we do A[i]=A[i] XOR opn (here "XOR" is bitwise operation).

    Operation 4: SUM L R

    We want to know the result of A[L]+A[L+1]+...+A[R].

    Now can you solve this easy problem?

    Input

    The first line of the input contains an integer T, indicating the number of test cases. (T≤100)

    Then T cases, for any case, the first line has two integers n and m (1≤n≤1,000,000, 1≤m≤100,000), indicating the number of elements in A and the number of operations.

    Then one line follows n integers A[0], A[1], ..., A[n-1] (0≤A[i]<16,0≤i<n).

    Then m lines, each line must be one of the 4 operations above. (0≤opn≤15)

    Output

    For each test case and for each "SUM" operation, please output the result with a single line.

    Sample Input

    1
    4 4
    1 2 4 7
    SUM 0 2
    XOR 5 0 0
    OR 6 0 3
    SUM 0 2

    Sample Output

    7
    18

    Hint

    A = [1 2 4 7]

    SUM 0 2, result=1+2+4=7;

    XOR 5 0 0, A=[4 2 4 7];

    OR 6 0 3, A=[6 6 6 7];

    SUM 0 2, result=6+6+6=18.

    代码如下:

    #include <stdio.h>
    #include <string.h>
    const int N = 1000005;
    
    int c, res, a[N*4][4], flag[N*4][4], len[N*4];
    
    void pushDown( int rt )
    {
        int ls = 2 * rt; int rs = ls | 1;
        for( int i = 0; i < 4; ++i )
        {
            if( flag[rt][i] == -1 ) continue;
            if( flag[rt][i] == 0 || flag[rt][i] == 1 )
            {
                a[ls][i] = ( flag[ls][i] = flag[rt][i] ) * len[ls];
                a[rs][i] = ( flag[rs][i] = flag[rt][i] ) * len[rs];
                flag[rt][i] = -1;
            }
            else if( flag[rt][i] == 3 )
            {
                flag[rt][i] = -1;
            }
            else
            {
                a[ls][i] = len[ls] - a[ls][i];
                if( flag[ls][i] == -1 ) flag[ls][i] = 2;
                else flag[ls][i] ^= 1;
                a[rs][i] = len[rs] - a[rs][i];
                if( flag[rs][i] == -1 ) flag[rs][i] = 2;
                else flag[rs][i] ^= 1;
                flag[rt][i] = -1;
            }
    
        }
    }
    
    void pushUp( int rt )
    {
        int ls = 2 * rt; int rs = ls | 1;
        for( int i = 0; i < 4; ++i )
            a[rt][i] = a[ls][i] + a[rs][i];
    }
    
    void build( int l, int r, int rt )
    {
        len[rt] = r - l + 1;
        if( l == r )
        {
            scanf("%d", &c);
            for( int i = 0; i < 4; ++i )
                a[rt][i] = ( 1 & (c>>i) );
        }
        else
        {
            int mid = ( l + r ) / 2;
            build(l, mid, 2 * rt);
            build(mid + 1, r, 2 * rt + 1);
            pushUp( rt );
        }
    }
    
    void OR( int rt, int opn )
    {
        for( int i = 0; i < 4; ++i )
        {
            if( !( (opn>>i) & 1 ) ) continue;
            flag[rt][i] = 1;
            a[rt][i] = len[rt];
        }
    }
    
    void ADD( int rt, int opn )
    {
        for( int i = 0; i < 4; ++i )
        {
            if( (opn>>i) & 1 ) continue;
            flag[rt][i] = 0;
            a[rt][i] = 0;
        }
    }
    
    void XOR( int rt, int opn )
    {
        for( int i = 0; i < 4; ++i )
        {
            if( !( (opn>>i) & 1 ) ) continue;
            if( flag[rt][i] == -1 ) flag[rt][i] = 2;
            else flag[rt][i] ^= 1;
            a[rt][i] = len[rt] - a[rt][i];
        }
    }
    
    void query( int l, int r, int rt, const int aa, const int bb )
    {
        if( aa <= l && r <= bb )
        {
            res = res + a[rt][0] + a[rt][1] * 2 + a[rt][2] * 4 + a[rt][3] * 8;
            return;
        }
        pushDown( rt );
        int mid = ( l + r ) / 2;
        int ls = 2 * rt; int rs = ls | 1;
        if( mid >= aa ) query( l, mid, ls, aa, bb );
        if( mid < bb ) query( mid + 1, r, rs, aa, bb );
    }
    
    void update( int l, int r, int rt, const int aa, const int bb, const int opn, const int f )
    {
        if( aa <= l && r <= bb )
        {
            switch( f )
            {
                case 0: OR( rt, opn ); break;
                case 1: ADD( rt, opn ); break;
                case 2: XOR( rt, opn ); break;
            }
            return;
        }
        pushDown( rt );
        int mid = ( l + r ) / 2;
        int ls = 2 * rt; int rs = ls | 1;
        if( mid >= aa ) update( l, mid, ls, aa, bb, opn, f );
        if( mid < bb ) update( mid + 1, r, rs, aa, bb, opn, f );
        pushUp( rt );
    }
    
    int main()
    {
        int t, n, m, aa, bb, opn; char cmd[4];
        scanf("%d", &t);
        while( t-- )
        {
            memset( flag, -1, sizeof(flag) );
            scanf("%d%d", &n, &m);
            build(0, n-1, 1);
            while( m-- )
            {
                scanf("%s", cmd);
                if( cmd[0] == 'S' )
                {
                    scanf("%d%d", &aa, &bb);
                    res = 0;
                    query( 0, n - 1, 1, aa, bb );
                    printf("%d
    ", res);
                }
                else
                {
                    scanf("%d%d%d", &opn, &aa, &bb);
                    switch( cmd[0] )
                    {
                        case 'O': update(0, n-1, 1, aa, bb, opn, 0); break;
                        case 'A': update(0, n-1, 1, aa, bb, opn, 1); break;
                        case 'X': update(0, n-1, 1, aa, bb, opn, 2); break;
                        default : break;
                    }
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    SSL
    Linux apache自建证书搭建https
    bat 命令
    Centos 搭建wordpress个人博客
    Python 递归删除非空目录(包括子目录以及文件)
    使用Mongo索引需要注意的几个点
    在phpWeChat中生成公众号 jssdk 各个参数(PHP)
    同等条件下,mongo为什么比mysql快?
    在phpWeChat里生成一个临时二维码(非微信二维码)
    .NetCore下使用Prometheus实现系统监控和警报 (二)Linux安装
  • 原文地址:https://www.cnblogs.com/lovychen/p/3434373.html
Copyright © 2020-2023  润新知