题意:
给出一个序列{a1,a2....an},长度为n,和一个m;
问有多少个区间,连续或完(即有几对(i,j) ai | ai+1 | ai+2.....|aj)的结果小于m;
思路:
因为数字或完之后,只可能大于等于本身,不可能变小,因为1|1=1 ; 1|0 = 1; 0|0 = 0;
所以我们枚举左右边界,当连续或结果大于等于m后,就不必继续往后枚举右边界了,因为结果之后变大,肯定也都是大于等于m;
AC:
#include<cstdio>
#include<cstring>
#define ll long long
const int N = 100000 + 5;
ll num[N];
ll res[N];
int n;
ll m;
int main() {
int t;
int cas = 1;
scanf("%d",&t);
while(t--) {
ll ans = 0;
scanf("%d%lld",&n,&m);
for(int i = 1; i <= n; i++) {
scanf("%lld",&num[i]);
if(num[i] < m)
ans++;
}
for(int i = 1; i <= n; i++) {
ll tmp = num[i];
for(int j = i + 1; j <= n; j++) {
tmp |= num[j];
if(tmp >= m)
break;
ans++;
}
}
printf("Case #%d: %lld\n",cas++, ans);
}
}