Question
- I will give you a sequence, \ (Q \) times to ask how many subintervals in a range meet all the numbers in the Self-interval, and the result of bitwise AND calculation is the complete number of vertices.
It's what \ (lstete \) tells me...
What he told me not long ago, I can't do it anymore.
This is the question of finding subintervals within the interval.
Generally, to avoid weighting, you can consider hanging the query offline on the right end.
First, we can find a property
The result of bitwise AND operation on a number will not become larger.
This means that a non-stop number and operation can only be performed by \ (log \).
We consider a number as the range of the right endpoint.
The bitwise AND calculation values of these intervals are only \ (log \).
And the intervals with the same values are continuous.
We can modify the intervals with the same values.
As long as the binary bits ending with each number are preprocessed as the \ (1 \) bits
The position of the number nearest to it and that digit is \ (0 \)
You can find the breakpoints in these intervals.
The complexity of this operation is \ (O (qlognlog1e9) \)
So this question needs to be stuck .....
Codes
#include<bits/stdc++.h>using namespace std;const int N = 5e5 + 10;const int M = 30 + 1;unordered_map<int, bool> is;vector<pair<int, int>> Q[N];long long ans[N << 1];int a[N], pre[M][N];struct Segment_Tree {#define mid ((l + r) >> 1)#define ls (bh << 1)#define rs (ls | 1)#define lson ls, l, mid#define rson rs, mid + 1, r long long S[N << 2], lazy[N << 2]; void modify(int bh, int l, int r, long long val) { lazy[bh] += val; S[bh] += (r - l + 1) * val; } void pushup(int bh) { S[bh] = S[ls] + S[rs]; } void pushdown(int bh, int l, int r) { if(lazy[bh]) { modify(lson, lazy[bh]); modify(rson, lazy[bh]); lazy[bh] = 0; } } void build(int bh, int l, int r) { S[bh] = lazy[bh] = 0; if(l ^ r) build(lson), build(rson); } void update(int bh, int l, int r, int x, int y, long long z) { if(x <= l && r <= y) modify(bh, l, r, z); else { pushdown(bh, l, r); if(x <= mid) update(lson, x, y, z); if(y > mid) update(rson, x, y, z); pushup(bh); } } long long query(int bh, int l, int r, int x, int y) { long long res = 0; if(x <= l && r <= y) res += S[bh]; else { pushdown(bh, l, r); if(x <= mid) res += query(lson, x, y); if(y > mid) res += query(rson, x, y); } return res; }}T;int main(){ //freopen("c.in", "r", stdin); //freopen("c.out", "w", stdout); int t, n, q, x, y; for(long long i = 0; i * i <= INT_MAX; ++ i) is[i * i] = true; for(scanf("%d", &t); t -- ; ) { scanf("%d%d", &n, &q); for(int i = 1; i <= n; ++ i) scanf("%d", &a[i]); for(int i = 1; i <= q; ++ i) { scanf("%d%d", &x, &y); Q[y].push_back(make_pair(i, x)); } T.build(1, 1, n); for(int i = 1; i < n; ++ i) for(int j = 0; j < M; ++ j) { if(a[i] >> j & 1) pre[j][i + 1] = pre[j][i]; else pre[j][i + 1] = i; } for(int r = 1; r <= n; ++ r) { int val = a[r], pos = r; while(pos) { int last = 0; for(int j = 0; j < M; ++ j) if(val >> j & 1) last = max(last, pre[j][pos]); if(is[val]) T.update(1, 1, n, last + 1, pos, 1); pos = last, val &= a[last]; } for(; !Q[r].empty(); Q[r].pop_back()) { pair<int, int> now = Q[r].back(); ans[now.first] = T.query(1, 1, n, now.second, r); } } memset(pre, 0, sizeof(pre)); for(int i = 1; i <= q; ++ i) printf("%lld\n", ans[i]); } return 0;}
10-27 C line segment tree