#保序回归问题,单调栈,二分#洛谷 5294 [HNOI2019]序列
题目
给定一个长度为 \(n\) 的序列 \(A\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k\)。
第一次修改之前及每次修改之后,都要求你找到一个同样长度为 \(n\) 的单调不降序列 \(B\),
使得 \(\sum_{i=1}^n(A_i-B_i)^2\) 最小,并输出最小值。
需要注意的是每次操作的影响都是独立的,也即每次操作只会对当前询问造成影响。
\(n\leq 10^5,A\leq 10^9\)
分析
对于形如最小化 \(\sum C_i(A_i-m)^2\) 的问题,\(m\) 应取 \(\large \frac{\sum C_iA_i}{\sum C_i}\)
而且这个序列 \(B\) 等同于用单调递增的 \(m\) 去覆盖,这种问题可以用单调栈维护均值。
考虑比较独立的修改可以离线做,此时 \([1,x)\) 和 \((x,n]\) 的单调栈都可以求出来。
反向的单调栈原理相同,先倒着做一遍再把出入栈撤销。
修改的位置会修改中间一段,两边依旧是原来的单调栈,
所以可以二分右端点,其位置越靠前,答案越小;
当右端点二分的情况下,再二分左端点,其位置越靠后答案越小。
时间复杂度 \(O(n\log ^2 n)\)
代码
#include <cstdio>
#include <cctype>
#include <stack>
#define rr register
using namespace std;
const int N=100011,mod=998244353;
typedef long long lll; lll s[N];
struct node{int y,next;}q[N]; stack<int>K[N];
int wl[N],wr[N],a[N],_s[N],n,Q,as[N],Tol,Tor,stal[N],star[N],ans[N];
inline signed iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline signed mo(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline signed o(int x){return 1ll*x*x%mod;}
inline signed ksm(int x,int y){
rr int ans=1;
for (;y;y>>=1,x=1ll*x*x%mod)
if (y&1) ans=1ll*ans*x%mod;
return ans;
}
struct rec{
lll x; int y;
inline bool operator <=(const rec &t)const{
return (double)x*t.y<=(double)t.x*y;
}
inline signed ans(){return 1ll*o(x%mod)*ksm(y,mod-2)%mod;}
}cl[N],cr[N];
inline rec slope(int l,int r){return (rec){s[r]-s[l-1],r-l+1};}
inline signed Get(int x,int now){
rr int l=0,r=Tol;
while (l<r){
rr int mid=(l+r+1)>>1;
if (cl[mid]<=(rec){s[x-1]-s[stal[mid]]+now,x-1-stal[mid]}) l=mid;
else r=mid-1;
}
return l;
}
inline signed query(int now){
rr int l=0,r=Tor,mid,_l;
while (l<r){
_l=Get(star[mid=(l+r+1)>>1],now);
if ((rec){s[star[mid]-1]-s[stal[_l]]+now,star[mid]-1-stal[_l]}<=cr[mid]) l=mid;
else r=mid-1;
}
_l=Get(star[r],now);
return mo(mo(wl[_l],wr[r]),(rec){s[star[r]-1]-s[stal[_l]]+now,star[r]-stal[_l]-1}.ans());
}
signed main(){
n=iut(),Q=iut(),star[0]=n+1;
for (rr int i=1;i<=n;++i) s[i]=s[i-1]+(a[i]=iut());
for (rr int i=1;i<=n;++i) _s[i]=mo(_s[i-1],o(a[i]));
for (rr int i=1;i<=Q;++i){
rr int x=iut(),y=iut();
q[i]=(node){y-a[x],as[x]},as[x]=i;
}
for (rr int i=n;i;--i){
for (;Tor&&cr[Tor]<=slope(i,star[Tor]-1);K[i].push(star[Tor--]));
star[++Tor]=i,wr[Tor]=mo(wr[Tor-1],(cr[Tor]=slope(i,star[Tor-1]-1)).ans());
}
print(mo(_s[n],mod-wr[Tor]));
for (rr int i=1;i<=n;++i){
--Tor;
for (;!K[i].empty();K[i].pop())
star[++Tor]=K[i].top(),wr[Tor]=mo(wr[Tor-1],(cr[Tor]=slope(star[Tor],star[Tor-1]-1)).ans());
rr int now=mo(_s[n],mod-o(a[i]));
for (rr int j=as[i];j;j=q[j].next)
ans[j]=mo(now,mo(o(a[i]+q[j].y),mod-query(q[j].y)));
for (;Tol&&slope(stal[Tol]+1,i)<=cl[Tol];--Tol);
stal[++Tol]=i,wl[Tol]=mo(wl[Tol-1],(cl[Tol]=slope(stal[Tol-1]+1,i)).ans());
}
for (rr int i=1;i<=Q;++i) putchar(10),print(ans[i]);
return 0;
}
#保序回归问题,单调栈,二分#洛谷 5294 [HNOI2019]序列的更多相关文章
- 洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找)
洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1333275 这个题不是很 ...
- BZOJ1012最大数 [JSOI2008] 单调栈+二分
正解:单调栈+二分查找(or,线段树? 解题报告: 拿的洛谷的链接quq 今天尝试学习了下单调栈,然后就看到有个博客安利了这个经典例题?于是就去做了,感觉还是帮助了理解趴quqqqqq 这题,首先,一 ...
- 103 保序回归 isotonic regression
103 保序回归 isotonic regression 2016-03-30 11:25:27 bea_tree 阅读数 6895 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权 ...
- BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 8748 Solved: 3835[Submi ...
- scikit-learn一般实例之一:保序回归(Isotonic Regression)
对生成的数据进行保序回归的一个实例.保序回归能在训练数据上发现一个非递减逼近函数的同时最小化均方误差.这样的模型的好处是,它不用假设任何形式的目标函数,(如线性).为了比较,这里用一个线性回归作为参照 ...
- 机器学习:保序回归(IsotonicRegression):一种可以使资源利用率最大化的算法
1.数学定义 保序回归是回归算法的一种,基本思想是:给定一个有限的实数集合,训练一个模型来最小化下列方程: 并且满足下列约束条件: 2.算法过程说明 从该序列的首元素往后观察,一旦出现乱序现象停止该轮 ...
- Spark机器学习(3):保序回归算法
保序回归即给定了一个无序的数字序列,通过修改其中元素的值,得到一个非递减的数字序列,要求是使得误差(预测值和实际值差的平方)最小.比如在动物身上实验某种药物,使用了不同的剂量,按理说剂量越大,有效的比 ...
- bzoj 4709 [Jsoi2011]柠檬——单调栈二分处理决策单调性
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4709 题解:https://blog.csdn.net/neither_nor/articl ...
- Spark Mllib里如何采用保序回归做回归分析(图文详解)
不多说,直接上干货! 相比于决策树,保序回归的应用范围没有决策树算法那么广泛. 特别在数据处理较为庞大的时候,采用保序回归做回归分析,可以极大地节省资源,从而提高计算效率. 保序回归的思想,是对数据进 ...
- 51NOD 1962 区间计数 单调栈+二分 / 线段树+扫描线
区间计数 基准时间限制:1.5 秒 空间限制:262144 KB 分值: 80 两个数列 {An} , {Bn} ,请求出Ans, Ans定义如下: Ans:=Σni=1Σnj=i[max{ ...
随机推荐
- Windows11补丁更新后无法使用Wifi和蓝牙
最近在我的ThinkPAD T14上更新了Windows 11补丁,重启后Wifi和蓝牙鼠标都不能使用了,无法连接Wifi网络,也无法添加蓝牙设备. 使用厂家自带的管理工具查看驱动都是最新的,一度不知 ...
- 亲测可行,Android Studio 查看源码出现 Source for ‘Android API xxx Platform’ not found 的解决方法
亲测可行,Android Studio 查看源码出现 Source for 'Android API xxx Platform' not found 的解决方法 如标题中的问题,产生的原因就是 SDK ...
- React 组件之状态
没有什么是不可能的,只是需要找到正确的方法. 1. 什么是状态? 状态就是组件内部特有数据的载体(组件数据挂载方式),改变数据页面就会刷新,由组件自己设置和更改,也就是说由组件自己产生.维护,使用状态 ...
- Spring-Cloud集成redis-cluster
前言 系统之前接入的是单点redis,为了条系统高可用能力,特增加集成redis-cluster集群的步骤 依赖库引入 <dependency> <groupId>org.sp ...
- 【Azure Key Vault】使用Azure CLI获取Key Vault 机密遇见问题后使用curl命令来获取机密内容
问题描述 在使用Azure Key Vault的过程中,遇见无法获取机密信息,在不方便直接写代码的情况下,快速使用Azure CLI指令来验证当前使用的认证是否可以获取到正确的机密值. 使用CLI的指 ...
- 【Azure IoT Hub】从设备端如何向IOT发送海量数据,可以使用从设备到IoT连接的直接传输吗?如何把IoT Hub中的数据存储到Azure Storage中?
问题描述 IoT Hub 从设备端如何向IOT发送海量数据,可以使用从设备到IOT连接的直接传输吗?还是需要另外开启连接.另外,消息路由和上传文件使用的连接是否就是设备到IOT建立的连接?还是需要额外 ...
- 【Azure Cloud Services】云服务频繁发生服务器崩溃的排查方案
问题描述 云服务(Cloud Services)在使用期间,频繁发生崩溃事件,在崩溃期间,查看CPU负载为100%,而且同时伴随以下情况: 部署在云服务上的应用无法访问 远程连接云服务实例(RDP)访 ...
- 【Azure Developer】解答《美丽的数学》一书中P120页的一道谜题:寻找第四个阶乘和数
一道谜题 在观看<美丽的数学>一书中,在120页中有一道谜题: 数字145被称为一个阶乘和数, 因为它具有以下有趣的属性,如果我们将它的各位数字的阶乘相加,会得到该数字本身 1! +4! ...
- nginx应用及性能调优
1. Nginx 反向代理实现 说反向代理之前 先说什么是正向代理, 正向代理是指客户端通过 代理服务器访问目标服务器,客户端直接访问代理服务器,在由代理服务器访问目标服务器并返回客户端并返回 . 例 ...
- jquery ui autocomplete ajax返回数据自定义显示
1.body里面的内容 <input type="text" class="inputTxt" id="txtJigou" autoc ...