Codeforces - Friends and Subsequences

题目链接:Codeforces - Friends and Subsequences


很显然max和min的前缀和具有单调性。

所以我们枚举左端点,二分右端点即可。

AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10;
int n,a[N],b[N];	long long res;
int mx[N<<2],mi[N<<2];
void build(int p,int l,int r){
	if(l==r){mx[p]=a[l],mi[p]=b[l];	return;}
	int mid=l+r>>1;
	build(p<<1,l,mid);	build(p<<1|1,mid+1,r);
	mx[p]=max(mx[p<<1],mx[p<<1|1]);
	mi[p]=min(mi[p<<1],mi[p<<1|1]);
}
int askmax(int p,int l,int r,int ql,int qr){
	if(l==ql&&r==qr)	return mx[p];
	int mid=l+r>>1;
	if(qr<=mid)	return askmax(p<<1,l,mid,ql,qr);
	else if(ql>mid)	return askmax(p<<1|1,mid+1,r,ql,qr);
	else	return max(askmax(p<<1,l,mid,ql,mid),askmax(p<<1|1,mid+1,r,mid+1,qr));
}
int askmin(int p,int l,int r,int ql,int qr){
	if(l==ql&&r==qr)	return mi[p];
	int mid=l+r>>1;
	if(qr<=mid)	return askmin(p<<1,l,mid,ql,qr);
	else if(ql>mid)	return askmin(p<<1|1,mid+1,r,ql,qr);
	else	return min(askmin(p<<1,l,mid,ql,mid),askmin(p<<1|1,mid+1,r,mid+1,qr));
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++)	scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)	scanf("%d",&b[i]);
	build(1,1,n);
	for(int i=1;i<=n;i++){
		int x0,x1;	int l=i,r=n;
		while(l<r){
			int mid=l+r>>1;
			if(askmax(1,1,n,i,mid)>=askmin(1,1,n,i,mid))	r=mid;
			else	l=mid+1;
		}
		x0=r;
		if(askmax(1,1,n,i,x0)>askmin(1,1,n,i,x0))	continue;
		l=x0,r=n;
		if(askmax(1,1,n,i,n)==askmin(1,1,n,i,n))	x1=n;
		else{
			while(l<r){
				int mid=l+r>>1;
				if(askmax(1,1,n,i,mid)>askmin(1,1,n,i,mid))	r=mid;
				else	l=mid+1;
			}
			x1=r-1;
		}
		res+=(x1-x0+1);
	}
	cout<<res;
	return 0;
}
Codeforces - Friends and SubsequencesCodeforces - Friends and Subsequences 青烟绕指柔! 发布了506 篇原创文章 · 获赞 241 · 访问量 3万+ 私信 关注
上一篇:2020-01-28 matlab常用编程学习


下一篇:深度学习 高数知识