problem
solution
按照题意模拟单调栈。
求出对于 i i i 而言,当时单调栈的栈顶元素记为 p i p_i pi。
如果到 i i i 时,栈顶已经为 p i p_i pi 了,意味着这中间的所有元素要么是被 i i i 弹出,要么就是被 i i i 前面的某些元素弹出,这些元素又被 i i i 弹出。
总而言之,会发现当询问的 p i < l p_i<l pi<l 时 i i i 所代表的二元组就是成功的。
于是我们只需要求 [ l , r ] [l,r] [l,r] 内有多少个 i ∈ [ l , r ] s . t . p i < l i\in[l,r]\ s.t.\ p_i<l i∈[l,r] s.t. pi<l。
写个主席树,或者差分一下转化成树状数组二维数点都行。
code
#include <bits/stdc++.h>
using namespace std;
#define maxn 500005
struct node { int x, p, k, id; }q[maxn << 1];
int n, Q;
int a[maxn], b[maxn], p[maxn], t[maxn], ans[maxn];
stack < int > s;
void read( int &x ) {
x = 0; char s = getchar();
while( s < '0' or s > '9' ) s = getchar();
while( '0' <= s and s <= '9' ) {
x = ( x << 1 ) + ( x << 3 ) + ( s ^ 48 );
s = getchar();
}
}
void print( int x ) {
if( x > 9 ) print( x / 10 );
putchar( x % 10 + '0' );
}
namespace BIT {
void add( int x ) { x ++; for(;x <= n;x += x & -x) t[x] ++; }
int ask( int x ) { x ++; int cnt = 0; for(x;x;x -= x & -x) cnt += t[x]; return cnt; }
}
int main() {
read( n ), read( Q );
for( int i = 1;i <= n;i ++ ) read( a[i] );
for( int i = 1;i <= n;i ++ ) read( b[i] );
for( int i = 1;i <= n;i ++ ) {
while( ! s.empty() and (a[s.top()] == a[i] or b[i] >= b[s.top()]) ) s.pop();
if( ! s.empty() ) p[i] = s.top();
s.push( i );
}
for( int i = 1, l, r;i <= Q;i ++ ) {
read( l ), read( r );
q[i] = (node){ l - 1, l - 1, -1, i };
q[i + Q] = (node){ r, l - 1, 1, i };
}
sort( q + 1, q + (Q << 1 | 1), [](node a, node b){ return a.x < b.x; } );
int j = 1; while( ! q[j].x ) j ++;
for( int i = 1;i <= n;i ++ ) {
BIT :: add( p[i] );
for( ;q[j].x == i and j <= (Q << 1);j ++ )
ans[q[j].id] += q[j].k * BIT :: ask( q[j].p );
}
for( int i = 1;i <= Q;i ++ ) print( ans[i] ), putchar( '\n' );
return 0;
}