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

A Bit Fun

                                                  Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2089    Accepted Submission(s): 1040

Problem Description

There are n numbers in a array, as a0, a1 ... , an-1, and another number m. We define a function f(i, j) = ai|ai+1|ai+2| ... | aj . 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 <= 230) Then n numbers come in the second line which is the array a, where 1 <= ai <= 230.

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

用个数组记录下各位出现的次数,就可以实现在一段区间或的值中减去一个元素。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <string>
#include <map>
#include <cstdlib>
#include <ctime>
using namespace std;
const int maxn=100000+1000;
int a[maxn];
int h[100];
int n,m;
void add(int x)
{
    int cur=0;
    while(x)
    {
        h[cur++]+=(x%2);
        x=x/2;
    }
}
void del(int x)
{
    int cur=0;
    while(x)
    {
        h[cur++]-=(x%2);
        x=x/2;
    }
}
int re()
{
    int ans=0;
    for(int i=0; i<35; i++)
    {
        if(h[i]>0)
            ans+=(1<<i);
    }
    return ans;
}
int main()
{
    int t,ca=1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        memset(h,0,sizeof(h));
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        int temp=0;
        long long ans=0;
        int cur=0;
        for(int i=0; i<n; i++)
        {
            cur=max(i,cur);
            while((temp|a[cur])<m&&cur<n)
            {
                temp=(temp|a[cur]);
                add(a[cur]);
                cur++;
            }
            if(cur>i)
            {
                ans+=(cur-i);
                del(a[i]);
                temp=re();
            }
        }
        printf("Case #%d: ",ca++);
        cout<<ans<<endl;
    }
    return 0;
}
时间: 2024-10-10 16:52:44

hdu 4737 A Bit Fun(2013 成都网络赛)的相关文章

HDU - 4734 F(x) (2013成都网络赛,数位DP)

题意:求0-B的满足<=F[A]的所有可能 思路:数位DP,记忆化搜索 #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; int A, B; int dp[20][200000]; int bit[20]; int dfs(int cur, int num, int flag) { if (cur == -

HDU 5875 Function -2016 ICPC 大连赛区网络赛

题目链接 网络赛的水实在太深,这场居然没出线zzz,差了一点点,看到这道题的的时候就剩半个小时了.上面是官方的题意题解,打完了才知道暴力就可以过,暴力我们当时是想出来了的,如果稍稍再优化一下估计就过了zzz.去年有一场现场赛也是n=1000,n^3过了,看来关键时刻实在做不出来就得大胆暴力啊. #include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+5; int a[maxn]

HDU 5880 Family View (2016 青岛网络赛 C题,AC自动机)

题目链接  2016 青岛网络赛  Problem C 题意  给出一些敏感词,和一篇文章.现在要屏蔽这篇文章中所有出现过的敏感词,屏蔽掉的用$'*'$表示. 建立$AC$自动机,查询的时候沿着$fail$指针往下走,当匹配成功的时候更新$f[i]$ $f[i]$表示要屏蔽以第$i$个字母结尾的长度为$f[i]$的字符串. 原文地址:https://www.cnblogs.com/cxhscst2/p/8452147.html

HDU - 4734 F(x) (2013成都网络游戏,数字DP)

意甲冠军:求0-B见面<=F[A]所有可能的 思维:数字DP,内存搜索 #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; int A, B; int dp[20][200000]; int bit[20]; int dfs(int cur, int num, int flag) { if (cur == -

HDU 4786 Fibonacci Tree (2013成都1006题) 最小生成树+斐波那契

题意:问生成树里能不能有符合菲波那切数的白边数量 思路:白边 黑边各优先排序求最小生成树,并统计白边在两种情况下数目,最后判断这个区间就可以.注意最初不连通就不行. 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include<cmath> 5 #define LL long long 6 using namespace std; 7 int t,n,m; 8 int

hdu 4790 Just Random (2013成都J题) 数学思路题 容斥

题意:在[a,b]  [c,d] 之间,和模p等于m的对数 详见代码 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include<cmath> 5 #define LL long long 6 using namespace std; 7 int T; 8 LL a,b,c,d,p,m; 9 10 LL gcd(LL a, LL b) { 11 return b ?

HDU 4291 A Short problem (2012成都网络赛,矩阵快速幂+循环节)

链接: click here~~ 题意: According to a research, VIM users tend to have shorter fingers, compared with Emacs users. Hence they prefer problems short, too. Here is a short one: Given n (1 <= n <= 1018), You should solve for g(g(g(n))) mod 109 + 7 where

HDU 5008 Boring String Problem(西安网络赛B题)

HDU 5008 Boring String Problem 题目链接 思路:构造后缀数组,利用height的数组能预处理出每个字典序开始的前缀和有多少个(其实就是为了去除重复串),然后每次二分查找相应位置,然后在往前往后找一下sa[i]最小的 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int

HDU 5025 Saving Tang Monk(广州网络赛D题)

HDU 5025 Saving Tang Monk 题目链接 思路:记忆化广搜,vis[x][y][k][s]表示在x, y结点,有k把钥匙了,蛇剩余状态为s的步数,先把图预处理出来,然后进行广搜即可 代码: #include <cstdio> #include <cstring> #include <queue> using namespace std; const int INF = 0x3f3f3f3f; const int N = 105; const int