萌新求救二次离线莫队,挂在了 #27 #47 上
查看原帖
萌新求救二次离线莫队,挂在了 #27 #47 上
355510
Lightwhite楼主2021/11/22 09:31

qq_emoji: kk巨佬们帮忙调一下吧

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

const ll kMaxN = 4e5 + 5;

struct interval {
  int left, right, identity, ans;
} inter[kMaxN];
struct node {
  int left, right, identity, opt;
  node (int left_, int right_, int identity_, int opt_) : left (left_), right (right_), identity (identity_), opt (opt_) {}
} ;
vector <node> que[kMaxN];
vector <int> v;
int n, m, k, len, arr[kMaxN], bucket[kMaxN], pos[kMaxN], block[kMaxN], ans[kMaxN];

bool compare (const interval & inter1, const interval & inter2) {
  if (block[inter1.left] ^ block[inter2.left]) {
    return block[inter1.left] < block[inter2.left];
  }
  return inter1.right < inter2.right;
}
int counter (int cur) {
  int ans = 0;
  while (cur) {
    if (cur & 1) {
      ans++;
    }
    cur >>= 1;
  }
  return ans;
}

int main () {
  ios :: sync_with_stdio (false);
  cin.tie (0), cout.tie (0);

  cin >> n >> m >> k;
  if (k > 14) {
    for (int i = 1; i <= m; i++) {
      cout << 0 << '\n';
    }
    return 0;
  }
  len = sqrt (n);
  for (int i = 0; i < 16384; i++) {
    if (counter (i) == k) {
      v.push_back (i);
    }
  }
  for (int i = 1; i <= n; i++) {
    cin >> arr[i];
    block[i] = (i - 1) / len + 1;
  }
  for (int i = 1; i <= m; i++) {
    cin >> inter[i].left >> inter[i].right;
    inter[i].identity = i;
  }

  sort (inter + 1, inter + m + 1, compare);
  for (int i = 1; i <= n; i++) {
    pos[i] = bucket[arr[i]];
    for (int j = 0; j < v.size (); j++) {
      bucket[arr[i] ^ v[j]]++;
    }
  }

  memset (bucket, 0, sizeof (bucket));
  int left_ = 1, right_ = 0;
  for (int i = 1; i <= m; i++) {
    if (left_ > inter[i].left) {
      que[right_].emplace_back (inter[i].left, left_ - 1, i, 1);
    }
    while (left_ > inter[i].left) {
      inter[i].ans -= pos[--left_];
    }

    if (right_ < inter[i].right) {
      que[left_ - 1].emplace_back (right_ + 1, inter[i].right, i, -1);
    }
    while (right_ < inter[i].right) {
      inter[i].ans += pos[++right_];
    }

    if (left_ < inter[i].left) {
      que[right_].emplace_back (left_, inter[i].left - 1, i, -1);
    }
    while (left_ < inter[i].left) {
      inter[i].ans += pos[left_++];
    }

    if (right_ > inter[i].right) {
      que[left_ - 1].emplace_back (inter[i].right + 1, right_, i, 1);
    }
    while (right_ > inter[i].right) {
      inter[i].ans -= pos[right_--];
    }
  }

  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < v.size (); j++) {
      bucket[arr[i] ^ v[j]]++;
    }
    for (int j = 0; j < que[i].size (); j++) {
      node temp = que[i][j];
      for (int t = temp.left; t <= temp.right; t++) {
        if (t <= i && k == 0) {
          inter[temp.identity].ans += temp.opt * (bucket[arr[t]] - 1);
        } else {
          inter[temp.identity].ans += temp.opt * bucket[arr[t]];
        }
      }
    }
  }

  for (int i = 1; i <= m; i++) {
    inter[i].ans += inter[i - 1].ans;
  }
  for (int i = 1; i <= m; i++) {
    ans[inter[i].identity] = inter[i].ans;
  }
  for (int i = 1; i <= m; i++) {
    cout << ans[i] << '\n';
  }
  return 0;
}
2021/11/22 09:31
加载中...