50 分暴力做法,求卡常。
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int n, q, block;
int stk[N], top;
int v[N], ans[N];
struct node {
int x, y;
bool operator<(const node &ert) const {
return (x != ert.x) && (y < ert.y);
}
} a[N];
struct query {
int l, r, id;
bool operator<(const query &ert) const {
if (l / block == ert.l / block) {
if (l / block & 1) return r > ert.r;
else return r < ert.r;
} return l < ert.l;
}
} Q[N];
struct BIT {
int c[N];
inline void add(int x, int val) {
for (; x <= n; x += x & (-x)) c[x] += val;
}
inline int query(int x) {
int res = 0;
for (; x; x -= x & (-x)) res += c[x];
return res;
}
} T;
inline void upd(int x) { T.add(v[x] + 1, 1); }
inline void del(int x) { T.add(v[x] + 1, -1); }
inline int rd() {
int x = 0; char ch = getchar();
for (; ch < 48 || ch > 57; ch = getchar());
for (; ch > 47 && ch < 58; ch = getchar())
x = (x << 1) + (x << 3) + (ch ^ 48);
return x;
}
inline void wt(int x) {
if (x > 9) wt(x / 10);
putchar(x % 10 + 48);
}
signed main() {
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
n = rd(), q = rd(); block = sqrt(n);
for (int i = 1; i <= n; ++i) a[i].x = rd();
for (int i = 1; i <= n; ++i) a[i].y = rd();
for (int i = 1; i <= n; ++i) {
while (top && !(a[i] < a[stk[top]])) top--;
v[i] = stk[top], stk[++top] = i;
}
for (int i = 1; i <= q; ++i)
Q[i].l = rd(), Q[i].r = rd(), Q[i].id = i;
sort(Q + 1, Q + q + 1);
int L = 1, R = 1; T.add(1, 1);
for (int i = 1; i <= q; ++i) {
while (Q[i].l < L) upd(--L);
while (Q[i].l > L) del(L++);
while (Q[i].r > R) upd(++R);
while (Q[i].r < R) del(R--);
ans[Q[i].id] = T.query(Q[i].l);
}
for (int i = 1; i <= q; ++i) wt(ans[i]), putchar(10);
}