Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*#pragma GCC optimize("Ofast")
- #pragma GCC optimize("unroll-loops")
- #pragma GCC target("avx,avx2,fma")*/
- #include <bits/stdc++.h>
- #define for1(i,a,b) for (int i = a; i <= b; i++)
- #define for2(i,a,b) for (int i = a; i >= b; i--)
- // #define int long long
- #define sz(a) (int)a.size()
- #define pii pair<int,int>
- #define pb push_back
- /*
- __builtin_popcountll(x) : Number of 1-bit
- __builtin_ctzll(x) : Number of trailing 0
- */
- const long double PI = 3.1415926535897932384626433832795;
- const int INF = 1000000000;
- const int MOD = 1000000007;
- const int MOD2 = 1000000009;
- const long double EPS = 1e-6;
- using namespace std;
- struct Query{
- int l, r, a, b, id;
- bool operator< (Query const& other) const{
- return r < other.r;
- }
- };
- int n, q, a, b, cur;
- int c[100005], res[100005], lst[100005], root[400005];
- int child[28900005][2], val[28900005];
- vector<Query> v;
- int init() {
- child[cur][0] = child[cur][1] = 0;
- val[cur] = 0;
- return cur++;
- }
- void add(int pos, int x) {
- for2(i,16,0) {
- bool t = x & (1 << i);
- if (!child[pos][t]) child[pos][t] = init();
- pos = child[pos][t];
- val[pos]++;
- }
- }
- void rev(int pos, int x) {
- for2(i,16,0) {
- bool t = x & (1 << i);
- pos = child[pos][t];
- val[pos]--;
- }
- }
- int solve(int pos) {
- int res = 0;
- for2(i,16,0) {
- bool t1 = a & (1 << i), t2 = b & (1 << i);
- if (!t2) {
- if (child[pos][t1]) pos = child[pos][t1];
- else break;
- }
- else {
- if (child[pos][t1]) res += val[child[pos][t1]];
- if (child[pos][t1 ^ 1]) pos = child[pos][t1 ^ 1];
- else break;
- }
- if (i == 0) {
- res += val[pos];
- break;
- }
- }
- return res;
- }
- void build(int id, int l, int r) {
- root[id] = init();
- if (l == r) return;
- int m = (l + r) >> 1;
- build(id * 2, l, m);
- build(id * 2 + 1, m + 1, r);
- }
- void update(int id, int l, int r, int pos, bool t) {
- if (!t) rev(root[id], c[pos]);
- else add(root[id], c[pos]);
- if (l == r) return;
- int m = (l + r) >> 1;
- if (pos <= m) update(id * 2, l, m, pos, t);
- else update(id * 2 + 1, m + 1, r, pos, t);
- }
- int query(int id, int l, int r, int tl, int tr) {
- if (l > tr || r < tl) return 0;
- if (l >= tl && r <= tr) {
- return solve(root[id]);
- }
- int m = (l + r) >> 1;
- return query(id * 2, l, m, tl, tr) + query(id * 2 + 1, m + 1, r, tl, tr);
- }
- signed main() {
- ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
- // freopen("cf.inp", "r", stdin);
- // freopen("cf.out", "w", stdout);
- cin >> n;
- for1(i,1,n) cin >> c[i];
- build(1, 1, n);
- cin >> q;
- for1(i,1,q) {
- int l, r, a, b;
- cin >> l >> r >> a >> b;
- v.push_back({l, r, a, b, i});
- }
- sort(v.begin(), v.end());
- int j = 0;
- for1(i,1,n) {
- if (lst[c[i]]) {
- update(1, 1, n, lst[c[i]], 0);
- }
- update(1, 1, n, i, 1);
- lst[c[i]] = i;
- while (j < q && v[j].r == i) {
- a = v[j].a; b = v[j].b;
- res[v[j].id] = query(1, 1, n, v[j].l, v[j].r);
- j++;
- }
- }
- for1(i,1,q) cout << res[i] << "\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment