cf1827B2

description#

对于一个长度为 n 且不存在相同元素的序列 a1...an(1n3e5) ,定义美丽值为将其排为有序序列的最小时间花费,排序过程中可以进行任意次如下操作:
每次将一个区间[L,R]排为有序,时间花费R-L
求给定数组的所有子数组(在原数组连续)的美丽值之和

solution#

  • 首先考虑给一个区间[L,R]排序的时候,我们进行的操作区间肯定不会重合,否则我们直接选合并后的区间进行一次操作肯定更优
  • 所以我们给[L,R]排序就相当于将其分为若干段,给每段操作排序一次即可(可能存在长度为1的段,该段时间花费为0)
  • 显然想让时间花费最少就要尽量分多段,区间[L,R]的美丽值为R-L-(段数-1)
  • 假设Lk<R,发现只有 max{aL,...ak}<min{ak+1...aR} ,才能让 k 作为一段的结束,所以该区间美丽值为 R-L-(符合条件的k的个数)
  • 现在考虑要求给定序列的所有子数组的美丽值之和,显然可以考虑每个点作为符合条件的k对应的L,R的情况数,但是这样即使预处理st表,复杂度也是 n2
  • 所以我们考虑对于 i(2in) ,当 min{ak+1...aR}=ai时,我们去找对应的(L,k,R)的数量
  • k 只能i 左边第一个满足 ak<ai 的位置
  • xk 左边第一个满足 ax>ai 的位置, L 只能在 [x+1,k] 之间取值
  • 类似的,令 yi 右边第一个满足 ay<ai 的位置, R 只能在 [i,y1] 之间取
  • 所以当前 i 对于答案的贡献是 (kx)(yi)
  • 最后答案再加上对于所有子数组的 RL 即可

查询每个数左边或者右边第一个小于自己的数可以单调栈 O(n) 预处理
查询左边第一个大于某个特定数可以线段树上二分 单次 O(logn) 在线查询

code#

cf1827B2
复制#include<bits/stdc++.h>
#define ll long long
#define L (rt<<1)
#define R (rt<<1|1)
using namespace std;

const int N=3e5+10;
int n,a[N],sta[N],tp,lx[N],rx[N];
int mx[N*4];
ll ans;

void build(int rt,int l,int r)
{
	if(l==r) return mx[rt]=a[l],void();
	int mid=(l+r)/2;
	build(L,l,mid),build(R,mid+1,r);
	mx[rt]=max(mx[L],mx[R]);
}

int Find(int rt,int l,int r,int p,int v)
{
	if(r<=p&&mx[rt]<=v) return -1;
	if(l==r) return l;
	int mid=(l+r)/2;
	if(p<=mid) return Find(L,l,mid,p,v);
	int tmp=Find(R,mid+1,r,p,v);
	if(tmp!=-1) return tmp;
	return Find(L,l,mid,p,v);
}

int main()
{
//	freopen("1.in","r",stdin);
	int cs; cin>>cs;
	while(cs--)
	{
		cin>>n;
		for(int i=1;i<=n;++i) cin>>a[i];
		a[0]=0,sta[tp=1]=0;
		for(int i=1;i<=n;++i)
		{
			while(tp&&a[sta[tp]]>a[i]) --tp;
			lx[i]=sta[tp],sta[++tp]=i;
		}
		a[n+1]=0,sta[tp=1]=n+1;
		for(int i=n;i>=1;--i)
		{
			while(tp&&a[sta[tp]]>a[i]) --tp;
			rx[i]=sta[tp],sta[++tp]=i;
		}
		a[0]=(int)1e9+1;
		build(1,0,n);
		ans=0;
		for(int i=2;i<=n;++i)
		{
			int k=lx[i];
			if(k==0) continue;
			int x=Find(1,0,n,k-1,a[i]),y=rx[i];
			ans-=1ll*(k-x)*(y-i);
		}
		for(int i=1;i<n;++i) ans+=1ll*i*(n-i);
		printf("%lld\n",ans);
	}
	return 0;
}
posted @   liuzhaoxu  阅读(65)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示
主题色彩