HDU 4737 A Bit Fun(2013成都网络赛)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4737


Problem Description
There are n numbers in a array, as a 0, a 1 ... , a n-1, and another number m. We define a function f(i, j) = a i|a i+1|a i+2| ... | a j . Where "|" is the bit-OR operation. (i <= j)
The problem is really simple: please count the number of different pairs of (i, j) where f(i, j) < m.
 

Input
The first line has a number T (T <= 50) , indicating the number of test cases.
For each test case, first line contains two numbers n and m.(1 <= n <= 100000, 1 <= m <= 2 30) Then n numbers come in the second line which is the array a, where 1 <= a i <= 2 30.
 

Output
For every case, you should output "Case #t: " at first, without quotes. The  t is the case number starting from 1.
Then follows the answer.
 

Sample Input
   
   
   
   
2 3 6 1 3 5 2 4 5 4
 

Sample Output
   
   
   
   
Case #1: 4 Case #2: 0
 

Source
2013 ACM/ICPC Asia Regional Chengdu Online

题意:

求有多少对f(i, j) < m!

PS:

维护两个指针!

代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100010;
int a[maxn];
int c[32];

int cal(int x, int v)
{
    int ret = 0;
    for(int i = 0; i <= 30; i++)
    {
        if(x&(1<<i))
        {
            c[i] += v;
        }
        if(c[i])
        {
            ret |= (1<<i);
        }
    }
    return ret;
}

int main ()
{
    int t;
    int n, m;
    int cas = 0;
    scanf("%d",&t);
    while(t--)
    {
        memset(c,0,sizeof(c));
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; i++)
        {
            scanf("%d",&a[i]);
        }

        int l = 0;
        LL ans = 0;
        for(int i = 0; i < n; i++)
        {
            int tt = cal(a[i], 1);
            while(tt >= m)
            {
                tt = cal(a[l++], -1);
            }
            ans += (i-l+1);
        }

        printf("Case #%d: %I64d\n",++cas,ans);
    }
    return 0;
}


你可能感兴趣的:(网络,HDU,成都)