[NOI Online 2022 提高组] 丹钓战(单调栈 + 树状数组 / 主席树)

problem

luogu-P8251

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值