曾经有道题是说给出一个数组a0, a1 ... , an-1,一个数字m,设 f(i, j) = ai + ai+1 + ai+2 + ... + aj ,求(i,j)使f(i,j) < m的数量
原理与这题一样,+ 换成 | ,需要换种数据结构,重载下运算符
#include <cstdio> #include <iostream> #include <cmath> #include <queue> #include <algorithm> #include <vector> // http://acm.hdu.edu.cn/showproblem.php?pid=4737 using namespace std; const int MAXN = 100005; const int NN = 31; const int CN = NN*sizeof(int); struct node { int bt[31], nm; node (){ nm = 0; memset(bt, 0, CN); } node (int a) { node(); nm = a; for (int i = 0; i< NN; ++i) { bt[i] = a & 0x1; a >>= 1; } } node operator + (const node &a) { node res; res.nm = nm | a.nm; for (int i = 0; i< NN; ++i) { res.bt[i] = bt[i] + a.bt[i]; } return res; } node operator - (const node &a) { node res; for (int i = 0; i< NN; ++i) { res.bt[i] = bt[i] - a.bt[i]; } for (int i = 0; i< NN; ++i) { if (res.bt[i]) { res.nm |= 1<<i; } } return res; } }; node da[MAXN]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif int t; scanf("%d", &t); for (int _ = 1; _ <= t; ++_) { printf("Case #%d: ", _); int n, m; scanf("%d%d", &n, &m); for (int i = 0; i< n; ++i) { int cc; scanf("%d", &cc); da[i] = node(cc); } node sum(0), tp; int res = 0; int i = 0, j =0; while (i < n) { while (j < n) { tp = sum + da[j]; if (tp.nm >= m) { if (i == j) { j = ++i; } else { res += j-i; sum = sum - da[i++]; } break; } else { ++j; sum = tp; } } if (j == n) { res += (n-i)*(n-i+1)/2; break; } } printf("%d\n", res); } return 0; }
hdu 4737 A Bit Fun
最新推荐文章于 2014-09-09 10:50:42 发布