zoukankan      html  css  js  c++  java
  • A

    You are given an array a consisting of n integers. A subarray (l, r) from array a is defined as non-empty sequence of consecutive elements al, al + 1, ..., ar.

    The beauty of a subarray (l, r) is calculated as the bitwise AND for all elements in the subarray:

    Beauty(l, r) = al & al + 1 & al + 2 & ... & ar

    Your task is to calculate the summation of the beauty of all subarrays (l, r) (1 ≤ l ≤ r ≤ n):

    Input

    The first line contains an integer T, where T is the number of test cases.

    The first line of each test case contains an integer n (1 ≤ n ≤ 105), where n is the size of the array a.

    The second line of each test case contains n integers a1, a2, ..., an (1 ≤ ai ≤ 106), giving the array a.

    Output

    For each test case, print a single line containing the summation of the beauty of all subarrays in the given array.

    Example

    Input
    2
    3
    7 11 9
    4
    11 9 6 11
    Output
    40
    48

    Note

    As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use scanf/printf instead of cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.

    A bitwise AND takes two equal-length binary representations and performs the logical AND operation on each pair of the corresponding bits, by multiplying them. Thus, if both bits in the compared position are 1, the bit in the resulting binary representation is 1 (1  ×  1 = 1); otherwise, the result is 0 (1  ×  0 = 0 and 0  ×  0 = 0). This operation exists in all modern programming languages, for example in language C++ and Java it is marked as &.

    In the first test case, the answer is calculated as summation of 6 subarrays as follow:

    Beauty(1, 1) + Beauty(l, 2) + Beauty(1, 3) + Beauty(2, 2) + Beauty(2, 3) + Beauty(3, 3)
    (7) + (7 & 11) + (7 & 11 & 9) + (11) + (11 & 9) + (9) = 40
    这个题目呢,看完题解就觉得不难了,我开始觉得这个比较难,因为对于位运算不是很熟悉,现在明白了,这种位运算最后转化成二进制去求解比较好,
    这个有个要求就是只对于连续的才去进行位运算,所以我们就把这个每一个数的位运算的值求出来,然后再把连续的进行位运算。
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 100;
    int num[maxn][30];
    
    int main()
    {
        int t;
        cin >> t;
        while (t--)
        {
            int n;
            cin >> n;
            for (int i = 1; i <= n; i++)
            {
                int x;
                scanf("%d", &x);
                for (int j = 0; j <= 20; j++)
                {
                    num[i][j] = (x >> j) & 1;
                }
            }
            int cnt = 0;
            ll ans = 0;
            for (int j = 0; j <= 20; j++)
            {
                cnt = 0;
                for (int i = 1; i <= n; i++)
                {
                    if (num[i][j]) cnt++;
                    else
                    {
                        ans += 1ll * cnt*(cnt + 1) / 2 * (1ll << j);
                        cnt = 0;
                    }
                }
                if (cnt) ans += 1ll * cnt*(cnt + 1) / 2 * (1ll << j);
            }
            printf("%I64d
    ", ans);
        }
        return 0;
    }
     
  • 相关阅读:
    连续竞价
    使用 Sonar 进行代码质量管理
    【转】jQuery.ajax向后台传递数组问题
    DevOps
    【转】赚钱的思维
    【转】如果有人让你推荐编程技术书,请叫他看这个列表
    Java学习记录-Jdk包简单介绍
    有两个指针pa,pb分别指向有两个数,a,b,请写一个函数交换两个指针的指向,也就是让pa指向b,让pb指向a
    有两个数a,b,请写一个函数交换a,b
    开辟一个二维数组,有10*8个元素,用随机数填充,按照下面的方法用函数实现查找一个数是否存在
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/10514685.html
Copyright © 2011-2022 走看看