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)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }
要么优秀要么生锈