Codeforces - Special Segments of Permutation

题目链接:Codeforces - Special Segments of Permutation


考虑分治最大值,然后启发式求答案。

ST表预处理出区间最大值的位置即可。


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],pos[N];	long long res;
int st[N][20],lg[N];
inline void build(){
	lg[0]=-1;
	for(int i=1;i<=n;i++)	lg[i]=lg[i>>1]+1;
	for(int i=1;i<=n;i++)	st[i][0]=i;
	for(int j=1;j<=17;j++)
		for(int i=1;i+(1<<j)-1<=n;i++)
	st[i][j]=a[st[i][j-1]]>=a[st[i+(1<<(j-1))][j-1]]?st[i][j-1]:st[i+(1<<(j-1))][j-1];
}
inline int ask(int l,int r){
	int t=lg[r-l+1];
	return a[st[l][t]]>=a[st[r-(1<<t)+1][t]]?st[l][t]:st[r-(1<<t)+1][t];
}
void solve(int l,int r){
	if(l>=r-1)	return ;
	int mid=ask(l,r),mx=a[mid];
	if(mid-l<=r-mid){
		for(int i=l;i<mid;i++)	if(pos[mx-a[i]]>mid&&pos[mx-a[i]]<=r)	res++;
	}else{
		for(int i=mid+1;i<=r;i++)	if(pos[mx-a[i]]>=l&&pos[mx-a[i]]<mid)	res++;
	}
	solve(l,mid-1),solve(mid+1,r);
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++)	scanf("%d",&a[i]),pos[a[i]]=i;	build();
	solve(1,n);
	cout<<res;
	return 0;
}
发布了725 篇原创文章 · 获赞 244 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104758377