首页 > 其他分享 >HNOI2016 序列 题解

HNOI2016 序列 题解

时间:2024-12-26 11:43:14浏览次数:3  
标签:int 题解 top pos stk HNOI2016 序列 using times

HNOI2016 序列 题解

我做离线版本时往了偏序方向想,但是发现非常麻烦。直到看到了在线版本的容斥做法,发现既好写又跑得快。

首先考虑容斥,我们不妨把一个询问 \([L,R]\) 中最小值的位置 \(pos\) 求出来。

  • 子区间跨过 \(pos\),贡献即 \((pos-L+1)\times(R-pos+1)\times a_{pos}\)。
  • 子区间在 \(pos\) 左侧。
  • 子区间在 \(pos\) 右侧。

对于子区间在 \(pos\) 左侧和右侧是等价的,我们讨论在左侧的情况,可以考虑容斥,经过尝试可以发现一下的构造方式是可行的。

以下我们记 \([l,r][L,R]\) 表示左端点在 \([l,r]\),右端点在 \([L,R]\) 的所有区间最小值的和。

那么

\[[L,pos-1][L,pos-1]=[L,n][L,n]-[pos,n][pos,n]-[L,pos-1][pos,n] \]

在这里我们运用了 \([L,pos-1][pos,n]\) 一定跨过 \(pos\) 的性质来求。我们看具体怎么做。

设 \(f_i=[i,n][i,n]\)。可以递推求 \(f_i\),有 \(f_i=f_{i+1}+[i,i][i,n]\)。

怎么求 \([i,i][i,n]\),考虑还可以递推,设 \(F_i=[i,i][i,n]\)。

考虑把最小值为 \(a_i\) 的区间一并贡献,那么设 \(r_i\) 表示 \(i\) 右侧第一个比 \(a_i\) 小的位置,对于 \(r_i\) 及其右侧的贡献就是 \(F_{r_i}\),所以就有

\[F_i=(r_i-i)\times a_i+F_{r_i} \]

\(r_i\) 可以从右往左扫一遍用单调栈求。

我们再来看 \([L,pos-1][pos,n]\),前面说了要运用它跨过 \(pos\) 的性质,由于 \(pos\) 是 \([L,R]\) 内最小的位置,所以 \([L,pos-1]\) 都不大于 \(pos\),于是就有等价

\[[L,pos-1][pos,n]=(pos-L)\times[pos][pos,n]=(pos-L)\times F_{pos} \]

那么这道题就做完了,瓶颈在于 RMQ,可以使用 ST 表做到 \(O(n\log n+Q)\),或者使用 \(O(n)\sim O(1)\) RMQ 做到 \(O(n+Q)\)。

代码难度较低,细节不多。

AC 代码:

using gen::init;
using gen::input;
using gen::output;
using gen::finish;
const int N=1e5+5;
int a[N];
pair<int,int> mn[17][N];
int get(int l,int r){
	int len=r-l+1;
	return min(mn[__lg(len)][l],mn[__lg(len)][r-(1<<__lg(len))+1]).second;
}
int stk[N],top=0;
int L[N],R[N];
ll f[N],F[N],g[N],G[N];
signed main(){
	read(n,Q,type);
	fo(i,1,n){
		read(a[i]);
		mn[0][i]={a[i],i};
		while(top&&a[stk[top]]>=a[i])--top;
		L[i]=stk[top];
		stk[++top]=i;
		F[i]=F[L[i]]+(ll)(i-L[i])*a[i];
		f[i]=f[i-1]+F[i];
	}
	stk[top=0]=n+1;
	fd(i,n,1){
		while(top&&a[stk[top]]>=a[i])--top;
		R[i]=stk[top];
		stk[++top]=i;
		G[i]=G[R[i]]+(ll)(R[i]-i)*a[i];
		g[i]=g[i+1]+G[i];
	}
	fo(i,1,__lg(n)){
		fo(j,1,n-(1<<i)+1){
			mn[i][j]=min(mn[i-1][j],mn[i-1][j+(1<<i-1)]);
		}
	}
	if(type==1)init();
	while(Q--){
		int l,r;
		if(type==1)input(l,r);
		else read(l,r);
		ull ans=0;
		int pos=get(l,r);
		ans=(ull)a[pos]*(pos-l+1)*(r-pos+1);
		ans+=g[l]-g[pos]-(ll)G[pos]*(pos-l)+f[r]-f[pos]-F[pos]*(r-pos);
		output(ans);
	}
	finish();
	return 0;
}

标签:int,题解,top,pos,stk,HNOI2016,序列,using,times
From: https://www.cnblogs.com/dccy/p/18632371

相关文章

  • 506 最长上升子序列II
    //506最长上升子序列II.cpp:此文件包含"main"函数。程序执行将在此处开始并结束。///*http://oj.daimayuan.top/course/22/problem/647给定一个长度为n的数组a1,a2,…,an,问其中的最长上升子序列的长度。也就是说,我们要找到最大的m以及数组p1,p2,…,pm,满足1≤p1......
  • VMware15如何安装?附安装包和序列号
    前言大家好,我是小徐啊。VMware是我们在Java开发中,常用的一款工具,可以让我们开启虚拟机,这样就可以有linux的环境了。但是VMware一般是需要序列号的,今天小徐就来介绍下如何安装VMware,以及提供序列号。文末附获取方式。如何安装VMware首先,双击下安装包,开始安装。点击下一步按钮。......
  • 创建用于预测序列的人工智能模型,评估模型的能力。
    上一篇:《创建用于预测序列的人工智能模型(三),训练模型》序言:对于当前的动则几千亿的大语言模型来说,训练的过程可以持续几天几周基于几个月,这取决于拥有的硬件数量以及总要训练的参数。模型训练完成后就进入模型的评估验证过程,一般会不断的重复直到优化完成。评估人工智能模型的性......
  • 蓝桥杯 第 24 场 强者挑战赛 题解上(1-3题)
    原题链接https://www.lanqiao.cn/oj-contest/senior-24/   标记名字【算法赛】一条横幅,在1/N,2/N,3/N···(N-1)/N的地方标记一次,若之前标记过这则不用再标记,求f(N)=此时新标记的个数。 上思路读懂题后,重点在于确定该题的思考方向,也就是,新标记的点......
  • P11331 题解
    blog。写了好几天,人都要死了。提供一个不同的切入口,方便大家理解这个分段是在干嘛,以及一个更容易的线段树DS。题解一堆废话,大家看看就行(\(O(N^3)\)先把\(a_i\ne-1\)且无论如何无法成为前缀max的位置ban掉。由于答案只与premax的位置有关,于是设\(dp_{i,j}\)表示确定......
  • P10936 导弹防御塔 题解
    题目链接题目大意城堡有m个敌人、n个能发射导弹的防御塔。导弹的速度固定,都为v。导弹需要T1秒发射,T2分钟冷却,还需要防御塔到敌人距离的dis/v的时间。给定防御塔和敌人的坐标,求需要多少分钟能够消灭所有敌人。推导思路如果短的时间能够消灭所有敌人,则长的也一定能。所......
  • P10952 聚会 题解
    题目链接题目大意对于一棵树,求出一个点对于给定的三个点(以下简称$x$,$y$,$z$且可以重复)距离最短。题解对于点的距离,不难想到LCA处理。而对于本题,则有两种情况。第一问三点中有一为另外两个点的祖先时,所求目标点(以下简称$v$)的深度(简称$d_v$)一定在三点深度之间。三......
  • rust-analyzer 引入含有openssl包报错(openssl未找到)问题解决方案
    1.下载openssl编译后的包https://slproweb.com/products/Win32OpenSSL.html选择完全包2.安装注意下面这一步把dll安装到/bin所在的同级目录一路回车,最后的捐款可以不选3.设置环境变量经过实验,主要的环境变量有3个OPENSSL_DIR="C:\ProgramFiles\OpenSSL-Win64"这......
  • 105. 从前序与中序遍历序列构造二叉树
    题目链接解题思路:首先我们得知道人工怎么建这棵树。先序遍历[0,R1]第一个节点,就是根。然后我们在中序遍历[0,R2]找到根的位置,假如是x,那么,中序遍历中[0,x-1]就是左子树,中序遍历中[x+1,R2]就是右子树。那么先序遍历呢?左子树节点个数是x个,先序遍历是要先遍历完左子树,才能到......
  • ARC101E题解
    前言此片题解大致按照笔者做题思路进行讲解。简要题意有一棵树,树上有偶数个节点。你需要给这些点两两配对,一组已经配对的点会将两点之间的树边进行一次覆盖。一组合法方案需要满足树上所有边都被覆盖至少一次,求合法方案数。数据范围:\(n\le5000\)。思路首先我们去观察题目性......