1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include <bits/stdc++.h> #define rep(i, x, y) for (int i = x; i <= y; i++) #define cnt(x) __builtin_popcount(x) #define pb push_back using namespace std;
typedef long long ll; const int N = 1e5 + 5, V = 16390; int n, m, K, unit; int a[N], bin[V]; ll ans[N], pre[N]; struct Ques { int l, r, id; ll ans; } q[N]; struct atom { int l, r, id, op; atom(int L, int R, int Id, int Op) { l = L, r = R, id = Id, op = Op; } }; vector<int> buc; vector<atom> vec[N];
bool cmp(Ques a, Ques b) { return a.l / unit == b.l / unit ? a.r < b.r : a.l < b.l; }
int main() { cin >> n >> m >> K; if (K > 14) { rep(i, 1, m) puts("0"); return 0; } unit = n / sqrt(m); rep(i, 1, n) { scanf("%d", &a[i]); } rep(i, 1, m) { scanf("%d%d", &q[i].l, &q[i].r); q[i].id = i; } sort(q + 1, q + m + 1, cmp); rep(i, 0, 16383) if (cnt(i) == K) buc.pb(i); rep(i, 1, n) { pre[i] = bin[a[i]] + pre[i - 1]; for (int j = 0; j < buc.size(); j++) ++bin[a[i] ^ buc[j]]; } int L = 1, R = 0; rep(i, 1, m) { int l = q[i].l, r = q[i].r; ll &x = q[i].ans; if (L > l) vec[R].pb(atom(l, L - 1, i, 1)), x -= pre[L - 1] - pre[l - 1], L = l; if (R < r) vec[L - 1].pb(atom(R + 1, r, i, -1)), x += pre[r] - pre[R], R = r; if (L < l) vec[R].pb(atom(L, l - 1, i, -1)), x += pre[l - 1] - pre[L - 1], L = l; if (R > r) vec[L - 1].pb(atom(r + 1, R, i, 1)), x -= pre[R] - pre[r], R = r; } memset(bin, 0, sizeof(bin)); rep(i, 1, n) { for (int j = 0; j < buc.size(); j++) ++bin[a[i] ^ buc[j]]; for (int j = 0; j < vec[i].size(); j++) { atom t = vec[i][j]; rep(k, t.l, t.r) { if (k <= i && !K) q[t.id].ans += t.op * (bin[a[k]] - 1); else q[t.id].ans += t.op * bin[a[k]]; } } } rep(i, 1, m) q[i].ans += q[i - 1].ans; rep(i, 1, m) ans[q[i].id] = q[i].ans; rep(i, 1, m) printf("%lld\n", ans[i]); return 0; }
|