2017 ACM Jordanian Collegiate Programming Contest (1/13)

G. WiFi Password

题意

给一个n个数的数组, 询问小于等于v的或(or)最大区间,or区间(l<=x<=r)的定义:a【l】|a【l+1】|......|a【r】

(一共有128次输入,n <= 1e5,v<=3e5,a【i】 <= 2e5)


分析

对每一个数二进制位进行考虑,然后双指针的扫一下, 双指针扫的时候注意指针的位置

时间复杂度(T * n * 32)


 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 10;

int k[50];
int n,v;
int a[maxn];

int main()
{
    int t;
    freopen("wifi.in", "r", stdin);
    scanf("%d", &t);
    while(t--)
    {
        memset(k, 0, sizeof(k));
        scanf("%d%d", &n, &v);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
        }
        int l = 1, r = 1;
        int maxx = 0;
        int ans = 0;
        while(l<=n && r<=n)
        {
                ans|=a[r];
                for(int i = 0; i < 32; i++)
                {
                    if(a[r]&(1<<i))
                        k[i]++;
                }
            while(ans > v)
            {
                for(int i = 0; i < 32; i++)
                {
                    if(a[l]&(1<<i))
                    {
                        k[i]--;
                        if(!k[i])
                        {
                            ans^=(1<<i);
                        }
                    }
                }
                l++;
            }
            maxx = max(r-l+1, maxx);
            r++;
        }
        printf("%d\n", maxx);
    }
    return 0;
}
View Code

 

posted @ 2017-11-13 20:03  Superwalker  阅读(213)  评论(0编辑  收藏  举报