题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4737
解题思路:
题目大意:
给定一个长度为n的序列,现在问说有多少对i,j满足 f(i,j)<m.
算法思想:
Twopointer,将每个数拆分成二进制形式,然后维护连个指针l,r,保证f(l, r) < m,那么当i = l时,对应的j就有r - l + 1种选择方法。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 100005;
int c[35],a[maxn];
int add(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;
}
ll solve(){
int n,m;
memset(c,0,sizeof(c));
scanf("%d%d",&n,&m);
int l = 0,sum = 0;
ll ret = 0;
for(int i = 0; i < n; i++){
scanf("%d",&a[i]);
sum = add(a[i],1);
while(sum >= m)
sum = add(a[l++],-1);
ret += (ll)(i-l+1);
}
return ret;
}
int main(){
int T,t = 1;
scanf("%d",&T);
while(T--){
ll ans = solve();
printf("Case #%d: %lld\n",t++,ans);
}
return 0;
}