結果

問題 No.1270 Range Arrange Query
ユーザー 👑 hos.lyric
提出日時 2020-10-23 22:52:08
言語 C++14
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 1,216 ms / 7,000 ms
コード長 4,937 bytes
コンパイル時間 1,346 ms
コンパイル使用メモリ 108,876 KB
実行使用メモリ 6,944 KB
最終ジャッジ日時 2024-07-21 12:01:11
合計ジャッジ時間 7,755 ms
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 15
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
template <class T, class S, class OpTT, class OpST, class OpSS>
struct SegmentTree {
const OpTT opTT;
const OpST opST;
const OpSS opSS;
const T idT;
const S idS;
int n;
vector<T> ts;
vector<S> ss;
SegmentTree(int n_, const OpTT opTT, const OpST opST, const OpSS opSS,
const T &idT, const S &idS)
: opTT(opTT), opST(opST), opSS(opSS), idT(idT), idS(idS) {
for (n = 1; n < n_; n <<= 1) {}
ts.assign(n << 1, idT);
ss.assign(n << 1, idS);
}
T &at(int a) {
return ts[n + a];
}
void build() {
for (int a = n; --a; ) ts[a] = opTT(ts[a << 1], ts[a << 1 | 1]);
}
T query(int a, int b, const S &s) {
return query(1, 0, n, a, b, s);
}
private:
T query(int u, int l, int r, int a, int b, const S &s) {
if (a < l) a = l;
if (b > r) b = r;
if (a >= b) return idT;
if (a == l && b == r) {
ts[u] = opST(s, ts[u], r - l);
ss[u] = opSS(s, ss[u]);
return ts[u];
}
const int uL = u << 1, uR = u << 1 | 1;
const int mid = (l + r) >> 1;
// speed-up: if (ss[u] != idS)
if (ss[u] != idS)
{
ts[uL] = opST(ss[u], ts[uL], mid - l);
ts[uR] = opST(ss[u], ts[uR], r - mid);
ss[uL] = opSS(ss[u], ss[uL]);
ss[uR] = opSS(ss[u], ss[uR]);
ss[u] = idS;
}
const T resL = query(uL, l, mid, a, b, s);
const T resR = query(uR, mid, r, a, b, s);
ts[u] = opTT(ts[uL], ts[uR]);
return opTT(resL, resR);
}
};
constexpr int MAX_N = 20010;
constexpr int MAX_Q = 20010;
#ifdef LOCAL
constexpr int B = 3;
#else
constexpr int B = 141;
#endif
int N, Q;
int A[MAX_N];
struct Query { int l, r, id; };
Query P[MAX_Q];
int ans[MAX_Q];
int l, r;
int bitL[MAX_N], bitR[MAX_N];
int now;
void bitAdd(int *bit, int pos, int val) {
for (int x = pos; x < N; x |= x + 1) bit[x] += val;
}
int bitSum(int *bit, int pos) {
int ret = 0;
for (int x = pos - 1; x >= 0; x = (x & (x + 1)) - 1) ret += bit[x];
return ret;
}
int opTT(int t0, int t1) { return min(t0, t1); }
int opST(int s, int t, int sz) { return s + t; }
int opSS(int s0, int s1) { return s0 + s1; }
using Seg = SegmentTree<int, int, decltype(&opTT), decltype(&opST), decltype(&opSS)>;
Seg *seg;
void addL() {
now += (l - bitSum(bitL, A[l] + 1));
now += bitSum(bitR, A[l]);
bitAdd(bitL, A[l], +1);
seg->query(0, A[l], +1);
++l;
}
void remL() {
--l;
bitAdd(bitL, A[l], -1);
now -= (l - bitSum(bitL, A[l] + 1));
now -= bitSum(bitR, A[l]);
seg->query(0, A[l], -1);
}
void addR() {
--r;
now += (l - bitSum(bitL, A[r] + 1));
now += bitSum(bitR, A[r]);
bitAdd(bitR, A[r], +1);
seg->query(A[r] + 1, N, +1);
}
void remR() {
now -= (l - bitSum(bitL, A[r] + 1));
now -= bitSum(bitR, A[r]);
bitAdd(bitR, A[r], -1);
seg->query(A[r] + 1, N, -1);
++r;
}
int main() {
for (; ~scanf("%d%d", &N, &Q); ) {
for (int i = 0; i < N; ++i) {
scanf("%d", &A[i]);
--A[i];
}
for (int q = 0; q < Q; ++q) {
scanf("%d%d", &P[q].l, &P[q].r);
--P[q].l;
P[q].id = q;
}
sort(P, P + Q, [](const Query &a, const Query &b) {
const int ax = a.l / B;
const int bx = b.l / B;
return ((ax != bx) ? (ax < bx) : (ax & 1) ? (a.r > b.r) : (a.r < b.r));
});
l = 0;
r = N;
fill(bitL, bitL + N, 0);
fill(bitR, bitR + N, 0);
now = 0;
seg = new Seg(N, &opTT, &opST, &opSS, N + 1, 0);
for (int j = 0; j < N; ++j) {
seg->at(j) = 0;
}
seg->build();
for (int q = 0; q < Q; ++q) {
// cerr<<"query "<<P[q].l<<" "<<P[q].r<<" "<<P[q].id<<endl;
for (; l < P[q].l; addL()) {}
for (; l > P[q].l; remL()) {}
for (; r > P[q].r; addR()) {}
for (; r < P[q].r; remR()) {}
// cerr<<" now = "<<now<<endl;
// cerr<<" seg:";for(int j=0;j<N;++j){cerr<<" "<<seg->query(j,j+1,0);}cerr<<endl;
ans[P[q].id] = 0;
ans[P[q].id] += now;
ans[P[q].id] += (r - l) * seg->query(0, N, 0);
}
for (int q = 0; q < Q; ++q) {
printf("%d\n", ans[q]);
}
}
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0