bzoj4540: [Hnoi2016]序列

BZOJ4540: [Hnoi2016]序列 (线段树) 传送门 题解: 这道题的线段树做法好神啊。。 考虑直接从111扫描到nnn,不断更新1~i1~i1\text{~}i到iii的最小值。 那么显然我们要对线段树支持区间覆盖, 区间求历史和。 然后我们可以构造矩阵来完成,对于每个节点构造⎛⎝⎜⎜svallen⎞⎠⎟⎟(svallen)\begin{pmatrix} s \\ val\\ len \end{pmatrix} 即可完成区间覆盖... 阅读详情

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4540

思路:又是莫队....

我们发现左右端点移动时,只会增加或删除某个点开头或结尾的区间

先考虑右端点从r移动到r+1

令p为[l,r]中最小值的位置

那么它会对新加的区间中的p-l+1个区间产生a[p]的贡献

另一些左端点在[p+1,r],右端点是r+1的区间怎么统计呢?

首先用单调栈求出l[i],r[i]表示向左第一个小于a[i]的数的位置,向右第一个小于等于a[i]的数的位置

(注意:一个是小于,一个是小于等于,这样是防止重复计算)

预处理出两个类似前缀和的数组sl[i]和sr[i]

其中sl[i]=sl[l[i]]+(i-l[i])*a[i],sr同理

表示以这个为结束的答案的前缀和

左端点在l[i]及以前的答案就是sl[l[i]],左端点在[l[i],i]之间的最小值肯定是a[i],所以答案加上(i-l[i])*a[i]


那么左端点在[p+1,r],右端点是r+1的区间对答案的贡献就是sl[r+1]-sl[p]


那么移动后,答案加上(p-l+1)*a[i]+sl[r]-sl[p]即可

左端点移动及删除类似

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
typedef long long ll;
const int maxn=100010,maxk=22,inf=1e9;
using namespace std;
int n,Q,sz,top,a[maxn],st[maxn][maxk],pw[maxk],stk[maxn],L[maxn],R[maxn],bel[maxn],lg[maxn];ll sl[maxn],sr[maxn],now,ans[maxn];
struct quer{int l,r,id;}q[maxn];
bool operator <(quer a,quer b){return bel[a.l]==bel[b.l]?a.r<b.r:bel[a.l]<bel[b.l];}
int getmin(int x,int y){return a[x]<a[y]?x:y;}
int calc(int x,int y){
	if (x>y) swap(x,y);
	int l=lg[y-x+1];
	//printf("x=%d y=%d log=%d minpos%d\n",x,y,l,getmin(st[x][l],st[y-pw[l]+1][l]));
	return getmin(st[x][l],st[y-pw[l]+1][l]);
}

void modifyl(int l,int r,int op){
	int p=calc(l,r);
	ll tmp=1ll*a[p]*(r-p+1)+sr[l]-sr[p];
	now+=op*tmp;
}

void modifyr(int l,int r,int op){
	int p=calc(l,r);
	ll tmp=1ll*a[p]*(p-l+1)+sl[r]-sl[p];
	now+=op*tmp;
}

void work(){
	sort(q+1,q+1+Q);now=a[1];
	for (int l=1,r=1,i=1;i<=Q;i++){
		//printf("i=%d\n",i);
		for (;r<q[i].r;r++) modifyr(l,r+1,1);
		for (;l>q[i].l;l--) modifyl(l-1,r,1);
		for (;r>q[i].r;r--) modifyr(l,r,-1);
		for (;l<q[i].l;l++) modifyl(l,r,-1);
		ans[q[i].id]=now;
	}
	for (int i=1;i<=Q;i++) printf("%lld\n",ans[i]);
}

int main(){
	//freopen("sequence1.in","r",stdin);freopen("sequence.out","w",stdout);
	scanf("%d%d",&n,&Q),sz=sqrt(n),lg[0]=-1;
	pw[0]=1;for (int i=1;i<=18;i++) pw[i]=pw[i-1]<<1;
	for (int i=1;i<=n;i++) lg[i]=lg[i>>1]+1,bel[i]=(i-1)/sz+1;
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	for (int i=1;i<=n;i++) st[i][0]=i;
	for (int j=1;j<=18;j++)
		for (int i=1;i<=n;i++){
			st[i][j]=st[i][j-1];
			if (i+pw[j-1]<=n) st[i][j]=getmin(st[i][j-1],st[i+pw[j-1]][j-1]);
			//printf("%d ",st[i][j]);
		}
	for (int i=1;i<=n;i++){
		while (top&&a[stk[top]]>=a[i]) R[stk[top--]]=i;
		stk[++top]=i;
	}
	while (top) R[stk[top--]]=n+1;
	for (int i=n;i;i--){
		while (top&&a[stk[top]]>a[i]) L[stk[top--]]=i;
		stk[++top]=i;
	}
	while (top) L[stk[top--]]=0;
	
	//for (int i=1;i<=n;i++) printf("i=%d L=%d R=%d\n",i,L[i],R[i]);
	for (int i=n;i;i--) sr[i]=sr[R[i]]+1ll*(R[i]-i)*a[i];
	for (int i=1;i<=n;i++) sl[i]=sl[L[i]]+1ll*(i-L[i])*a[i];
	//for (int i=1;i<=n;i++) printf("i=%d sl=%lld sr=%lld\n",i,sl[i],sr[i]);
	for (int i=1;i<=Q;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
	work();
	return 0;
}
/*
5 5
5 2 4 1 3
1 5
1 3
2 4
3 5
2 5

*/



SUMO仿真教程(1) ——安装环境的设置(Windows 10系统) SUMO安装环境的设置 目录一.SUMO下载的官方网址二.下载步骤:三.环境设置:1.打开设置环境变量的界面2.用户(Administrator)变量设置3.系统变量设置四.总述 一.SUMO下载的官方网址 sumo的下载地址: 二.下载步骤: 1.以sumo1.8.0为示例进行演示,点击下载地址; 2.选择Windows64位的安装版本,如下图所示: 3.点击对应版本会跳转到如下图所示的界面,等待几秒后会自动下载(温馨提示:请将下载路径提前设置好): 4.到目标存储路径下查看下载完成的SUMO(本 阅读详情

相关推荐

信创改造实战:SpringBoot项目迁移到宝兰德BES 9.5.5的完整避坑指南(附依赖配置)

本文详细介绍了将SpringBoot项目迁移到宝兰德BES 9.5.5中间件的完整流程,包括环境准备、依赖调整、Web.xml版本适配、部署配置优化及常见问题解决方案。特别针对信创改造需求,提供了排除Tomcat依赖、处理BES专用starter等实用技巧,帮助开发者顺利完成国产中间件迁移。

weixin_30825581的博客 1101

[HNOI2016] 序列(线段树 + 莫队 + 倍增)

我已经做魔怔了,这真的是我想出来的吗?我好佩服自己!

845

TI理想二极管在冗余电源中应用实例

深入探讨理想二极管如何提升冗余电源系统的效率与可靠性,通过实际应用案例展示其在电流隔离和自动切换中的优势,帮助工程师优化电源架构设计。

weixin_30653091的博客 991

【HNOI 2016】序列

【HNOI 2016】序列 Problem Description 给定长度为 \(n\) 的序列:\(a_1, a_2, \cdots , a_n\),记为 \(a[1 \colon n]\)。类似地,\(a[l \colon r]\)(\(1 \leq l \leq r \leq N\))是指序列:\(a_{l}, a_{l+1}, \cdot...

洛水·锦依卫's Blog 438

ADS交叉耦合振荡器VCO仿真

本文主要参考视频中如何使用进行ADS交叉耦合振荡器仿真和分析,由于视频中有诸多错误和视频清晰度较低,虽然视频博主及时改正,为了节省学习时间,可以直接参考本文。

qq_32589131的博客 5427

基于FPGA 外置qspi Flash的读写

fpga上实现flash读写代码

weixin_43498765的博客 4955

【线段树维护历史值/莫队】BZOJ4540 [Hnoi2016] 序列

【题目】 BZOJ 给定一个长度为nnn的序列aaa,QQQ次询问一段区间中所有连续子序列的最小值之和。 n,Q≤105,ai≤109n,Q\leq 10^5,a_i\leq 10^9n,Q≤105,ai​≤109 【解题思路】 这个标记是真的神奇啊。 不妨令fi,jf_{i,j}fi,j​表示左端点为iii,右端点为jjj的区间最小值。如果我们枚举右端点来更新这个数组,不难发现就是一个区间覆盖。...

MEET YOU FIRST TIME 350

传感器采集信息的频率(采样频率)

较高的采集频率通常能提供更详细的信息,但也会增加数据处理和存储的负担。在某些应用中,较高的采样频率可能是必要的,而在其他情况下,则可能会选择适当的低采样频率以降低功耗和数据处理压力。传感器采集信息的频率(采样频率)是指传感器在一定时间内对输入信号进行采样的次数。对于一些需要快速检测和响应的应用,如运动传感器、声音传感器等,高采样频率是至关重要的。高采样频率通常需要更多的功耗和更大的存储容量,因为产生的数据量更大。例如,对于快速运动的对象,较低的采样频率可能无法捕捉到运动的真实轨迹。

chen的博客 5345

【HNOI2016】序列(线段树)

题意扩展版:有两个长度为 nnn 的序列 a,ba,ba,b,你需要维护 mmm 次操作: 对 aaa 区间赋值。 给定 l,rl,rl,r,对于所有 i∈[l,r]i\in[l,r]i∈[l,r],执行 bi←bi+aib_i\gets b_i+a_ibi​←bi​+ai​。 询问区间 bbb 的和。 题解: 感觉整篇题解都有点表达不清,但是我也不清楚应该怎样表达才好。 考虑使用线段树,发现操作一和操作二的懒标记是不好合并的,因为会出现两个操作二中间夹着一个操作一的情况。 但我们可以这样:进行操作一时

ez_lcw的博客 543

CAPL学习之路-关键字

在capl中,关键字具有特殊的含义和用途,因此,不得将关键字用作变量或函数的名称 声明数据类型的关键字 可以用不同的关键字,声明或引用不同类型的数据 byte 声明一个字节的变量 word 声明两个字节的变量 dword 声明四个字节的变量 int 声明两个字节的整数 long 声明四个字节的变量 qword 声明八个字节的变量 char 声明一个字符串 float 声明一个浮点数,8个字节 double 声明一个浮点数,8个字节 定义一个结构体或枚举类型 struct struct Data { .

jasonj333 6108

Codex 100个真实案例 - 全系列总结与Codex最佳实践全解析

历经100个案例的淬炼,我们终于来到了终点!本篇是整个系列的压轴之作——全面回顾100个案例的分类统计、提炼Codex使用的核心技巧和最佳实践、总结Prompt工程的精华要点、剖析常见错误及解决方案、展望AI编程的未来趋势,并为不同水平的读者规划学习路径。这不仅是一篇总结,更是一本Codex实战手册!

yueyeguzhuo的专栏 136

[BZOJ]4540: [Hnoi2016]序列

题解: 这个题 出发点显然在 在左/右 加入一个元素对答案产生的贡献 首先大方向上 离线区间考虑单点贡献 我们选择莫队算法 问题是我们如何去处理转移的问题     $$ \sum_{i=l}^{r}min(a[i....r]) $$这个很容易得到 然后有个很显然的结论 若pos为区间{l,r]的最小值的出现位置 那么在右端点加入a[r]时[l,pos]都将是a[pos]产生贡献 那么我...

weixin_30608131的博客 149

RK3588开发笔记-MIPI-CSI接口视频解码芯片XS9922B调试

Rockchip RK3588 是一款高性能的处理器,支持多种摄像头接口,包括 MIPI(Mobile Industry Processor Interface)接口。MIPI是一种用于移动设备和嵌入式系统中的摄像头、显示器和其他传感器设备的串行接口标准。MIPI是MIPI联盟发起的为移动应用处理器制定的开放标准。CSI-2(Camera Serial Interface 2)是MIPI 联盟定义的另一种高速接口,主要用于摄像模组和处理器之间的连接。

flypig has a dream! 6864

Bzoj4540:[Hnoi2016]序列:莫队+RMQ

题目链接4540:[Hnoi2016]序列 考虑莫队算法,在移动一个端点的时候,假设要处理的区间为[l,r]切向左扩大区间,最小值所在位置为k,那么a[k]的贡献为(r-k+1)*a[k],即[k,r]的新增序列都以a[k]为最小值 还有一段区间[l,k-1]没有处理,设s[i]为以i为左端点的合法区间的答案,r[i]为i右侧第一个不大于a[i]的输的位置,那么s[i]=s[r[i]]+1ll

蜜の夜明け 735

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

bzoj4540: [Hnoi2016]序列 莫队算法

bzoj4540: [Hnoi2016]序列 Description   给定长度为n的序列:a1,a2,…,an,记为a[1:n]。类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar- 1,ar。若1≤l≤s≤t≤r≤n,则称a[s:t]是a[l:r]的子序列。现在有q个询问,每个询问给定两个数l和r,1≤l≤r ≤n,求a[l:r]的不同子序列的最小值之和。例如,...

maxtir的博客 310

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Bzoj4540: [Hnoi2016]序列

题面 传送门 Sol 处理出每个数aiaia_i之前第一个比它小的数al−1al−1a_{l-1}和后面第一个比它小的数ar+1ar+1a_{r+1} 那么左端点在[l,i][l,i][l,i]右端点在[i,r][i,r][i,r]的区间的最小值都是aiaia_i 把它看成是一个顶点(l,r)(l,r)(l,r)和(i,i)(i,i)(i,i)的矩形内的加法,每个数加上aiaia_i...

Cyhlnj 364

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

BZOJ4540: [Hnoi2016]序列

BZOJ4540: [Hnoi2016]序列 Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n]。 类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar-1,ar。 若1≤l≤s≤t≤r≤n,则称a[s:t]是a[l:r]的子序列。 现在有q个询问,每个询问给定两个数l和r,1≤l≤r≤n,求a[l:r]的不同子序列的最小值之和。 ...

weixin_30892763的博客 157

[BZOJ4540][线段树][单调栈]HNOI2016:序列

BZOJ4540 不想写了,看这个 下传的时候要推一下合并的式子,类似矩阵乘法 Code: #include<bits/stdc++.h> #define ll long long using namespace std; inline int read(){ int res=0,f=1;char ch=getchar(); while(!isdigit(ch)) {if(ch==...

romiqi 192

bzoj 4540: [Hnoi2016]序列 莫队算法

内测的时候不知道为什么死活想不出来QAQ。。。。        然后看完题解发现傻逼题。。T_T。。。       yy了一个线段树做法(仅理论),在区间[l,r]中保存以mid为中心向两侧的一个单调递减的数组,空间NlogN,显然只有这一个数组中的数对[l,r]的答案有贡献,然后统计一下前缀和二分查找不知道行不行。。。这样应该是O(Nlog^2N)的。        莫队就简单多了。首先用

lych的博客 1206

BZOJ 4540: [Hnoi2016]序列

4540: [Hnoi2016]序列 Time Limit:20 SecMemory Limit:512 MBSubmit:1078Solved:518[Submit][Status][Discuss] Description   给定长度为n的序列:a1,a2,…,an,记为a[1:n]。类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,...

weixin_30784945的博客 99

BZOJ 4540: [Hnoi2016]序列 莫队算法

Time Limit: 20 Sec Memory Limit: 512 MB Submit: 1412 Solved: 663Description给定长度为n的序列:a1,a2,…,an,记为a[1:n]。类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar-1,ar。若1≤l≤s≤t≤r≤n,则称a[s:t]是a[l:r]的子序列。现在有q个询问,每个询问给定两个数l

Monica 592

bzoj 4540: [Hnoi2016]序列

题意坑爹,不需要判断两个子串是否相等。 然后这道题几乎就是bzoj 4262了。 除了线段树做法,还可以用莫队 用单调队列预处理出L[i]表示i左边第一个小于a[i]的位置,R[i]表示i右边第一个小于a[i]的位置。 fl[i]表示以i为左端点的所有区间的答案,=a[i]*(R[i]-i)+fl[R[i]],因为[i,R[i])位置的贡献都是a[i],[R[i],n]这个区间的答案与fr

heheda_is_an_OIer的博客 817
上一篇: bzoj4538: [Hnoi2016]网络
下一篇: bzoj1455: 罗马游戏
thy_asdf
博客等级 码龄12年 16粉丝 186原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值