AT_abc389_f [ABC389F] Rated Range
定义
经过第一场比赛后,值域在
故线段树维护,每次找到大于等于
#include <bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define _for(i, a, b) for (int i = (a); i <= (b); i++)
#define _pfor(i, a, b) for (int i = (a); i >= (b); i--)
#define int long long
const int N = 5e5 + 5;
int n, Q;
struct edge {
int l, r;
}ed[N];
struct stu {
int ls[N << 2], rs[N << 2], maxn[N << 2], sum[N << 2], lazy[N << 2];
void push_up(int p) {
maxn[p] = max(maxn[p << 1], maxn[p << 1 | 1]);
sum[p] = sum[p << 1] + sum[p << 1 | 1];
}
void push_down(int p) {
if (lazy[p]) {
lazy[p << 1] += lazy[p]; maxn[p << 1] += lazy[p];
lazy[p << 1 | 1] += lazy[p]; maxn[p << 1 | 1] += lazy[p];
sum[p << 1] += (rs[p << 1] - ls[p << 1] + 1) * lazy[p];
sum[p << 1 | 1] += (rs[p << 1 | 1] - ls[p << 1 | 1] + 1) * lazy[p];
lazy[p] = 0;
}
}
void build(int p, int l, int r) {
ls[p] = l, rs[p] = r;
if (l == r) {
maxn[p] = sum[p] = l;
return;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
push_up(p);
}
void modify(int p, int L, int R, int l, int r) {
if (l <= L && R <= r) {
lazy[p]++;
sum[p] += (R - L + 1);
maxn[p]++;
return;
}
push_down(p);
int mid = (L + R) >> 1;
if (l <= mid) modify(p << 1, L, mid, l, r);
if (r > mid) modify(p << 1 | 1, mid + 1, R, l, r);
push_up(p);
}
int query_max(int p, int L, int R, int l, int r) {
if (l <= L && R <= r) return maxn[p];
push_down(p);
int mid = (L + R) >> 1, res = 0;
if (l <= mid) res = max(res, query_max(p << 1, L, mid, l, r));
if (r > mid) res = max(res, query_max(p << 1 | 1, mid + 1, R, l, r));
return res;
}
int query_sum(int p, int L, int R, int l, int r) {
if (l <= L && R <= r) return sum[p];
push_down(p);
int mid = (L + R) >> 1, res = 0;
if (l <= mid) res += query_sum(p << 1, L, mid, l, r);
if (r > mid) res += query_sum(p << 1 | 1, mid + 1, R, l, r);
return res;
}
}tr;
int getl(int x) {
int L = 1, R = N - 5;
while (L < R) {
int mid = (L + R) >> 1;
if (tr.query_max(1, 1, N - 5, 1, mid) >= x) R = mid;
else L = mid + 1;
}
return L;
}
int getr(int x) {
int L = 1, R = N - 5;
while (L < R) {
int mid = (L + R + 1) >> 1;
if (tr.query_max(1, 1, N - 5, 1, mid) <= x) L = mid;
else R = mid - 1;
}
return L;
}
signed main() {
cin >> n;
_for(i, 1, n) cin >> ed[i].l >> ed[i].r;
tr.build(1, 1, N - 5);
_for(i, 1, n) {
tr.modify(1, 1, N - 5, getl(ed[i].l), getr(ed[i].r));
}
cin >> Q;
while (Q--) {
int x;
cin >> x;
cout << tr.query_sum(1, 1, N - 5, x, x) << endl;
}
}