一个权值线段树 + 一个平衡树
为啥过不了啊
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
typedef long long ll;
inline int read()
{
int now=0,nev=1; char c=getchar();
while(c<'0' || c>'9') { if(c=='-') nev=-1; c=getchar();}
while(c>='0' && c<='9') { now=(now<<1)+(now<<3)+(c&15); c=getchar(); }
return now*nev;
}
const int N = 1e6 + 10;
int a[N], b[N], n, m;
int sta[N], stb[N], top = 1, pos[N], pre[N];
namespace Val_SEG{
struct Node{
int l, r, v;
} node[N << 1];
void pushup(int id){
node[id].v = max(node[id << 1].v, node[id << 1 | 1].v);
}
void build(int id, int l, int r){
node[id].l = l, node[id].r = r;
node[id].v = 0;
if(l == r) return;
int mid = (l + r) >> 1;
build(id << 1, l, mid), build(id << 1 | 1, mid + 1, r);
}
void upd(int id, int x, int v){
if(node[id].l == node[id].r) return void(node[id].v = v);
if(x <= node[id << 1].r) upd(id << 1, x, v);
else upd(id << 1 | 1, x, v);
pushup(id);
}
int query(int id, int l, int r){
if(node[id].r < l || node[id].l > r) return 0;
if(l <= node[id].l && node[id].r <= r) return node[id].v;
return max(query(id << 1, l, r), query(id << 1 | 1, l, r));
}
} // end Val_SEG
namespace FHQ_Treap{
const int INF = 2147483647;
struct node{
int lson, rson, size, key, val;
} p[N << 1];
int tot = 1, ROOT;
void pushup(int root){
if(!root) return;
p[root].size = p[p[root].lson].size + p[p[root].rson].size + 1;
}
int make(int val){
int root = ++tot;
p[root].val = val;
p[root].size = 1;
p[root].lson = p[root].rson = 0;
p[root].key = rand();
return root;
}
void split(int root, int val, int &x, int &y){
if(!root) return void(x = y = 0);
if(val >= p[root].val) {
x = root;
split(p[root].rson, val, p[root].rson, y);
} else {
y = root;
split(p[root].lson, val, x, p[root].lson);
}
pushup(root);
}
int merge(int x, int y){
if(!x || !y) return x + y;
if(p[x].key > p[y].key) {
p[x].rson = merge(p[x].rson, y);
pushup(x);
return x;
} else {
p[y].lson = merge(x, p[y].lson);
pushup(y);
return y;
}
}
void insert(int val){
int x, y;
split(ROOT, val - 1, x, y);
ROOT = merge(merge(x, make(val)), y);
}
int rank(int val){
int x, y, res;
split(ROOT, val - 1, x, y);
res = p[x].size;
ROOT = merge(x, y);
return res;
}
void build(){
ROOT = make(INF);
}
} // end FHQ_Treap
typedef pair<int, int> pii;
vector<int> que[N];
map<pii, int> ans;
int l[N], r[N];
int main()
{
//freopen("stack.in", "r", stdin);
//freopen("stack.out", "w", stdout);
n = read(), m = read();
for(int i = 1; i <= n; ++i) a[i] = read();
for(int i = 1; i <= n; ++i) b[i] = read();
for(int i = 1; i <= n; ++i){
while(top && (a[i] == sta[top] || b[i] >= stb[top])) --top;
pos[i] = ++top;
sta[top] = a[i], stb[top] = b[i];
}
Val_SEG::build(1, 1, n);
for(int i = 1; i <= n; ++i){
Val_SEG::upd(1, pos[i], i);
pre[i] = Val_SEG::query(1, 1, pos[i] - 1);
}
for(int i = 1; i <= m; ++i){
l[i] = read(), r[i] = read();
que[l[i] - 1].push_back(l[i]);
que[r[i]].push_back(l[i]);
}
FHQ_Treap::build();
for(int i = 1; i <= n; ++i){
FHQ_Treap::insert(pre[i]);
for(int j : que[i])
ans[pii(i, j)] = FHQ_Treap::rank(j);
}
for(int i = 1; i <= m; ++i){
printf("%d\n", ans[pii(r[i], l[i])] - ans[pii(l[i] - 1, l[i])]);
}
//fclose(stdin);
//fclose(stdout);
return 0;
}