题目

给定一个长度为 \(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]序列的更多相关文章

  1. 洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找)

    洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1333275 这个题不是很 ...

  2. BZOJ1012最大数 [JSOI2008] 单调栈+二分

    正解:单调栈+二分查找(or,线段树? 解题报告: 拿的洛谷的链接quq 今天尝试学习了下单调栈,然后就看到有个博客安利了这个经典例题?于是就去做了,感觉还是帮助了理解趴quqqqqq 这题,首先,一 ...

  3. 103 保序回归 isotonic regression

    103 保序回归 isotonic regression 2016-03-30 11:25:27 bea_tree 阅读数 6895   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权 ...

  4. BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 8748  Solved: 3835[Submi ...

  5. scikit-learn一般实例之一:保序回归(Isotonic Regression)

    对生成的数据进行保序回归的一个实例.保序回归能在训练数据上发现一个非递减逼近函数的同时最小化均方误差.这样的模型的好处是,它不用假设任何形式的目标函数,(如线性).为了比较,这里用一个线性回归作为参照 ...

  6. 机器学习:保序回归(IsotonicRegression):一种可以使资源利用率最大化的算法

    1.数学定义 保序回归是回归算法的一种,基本思想是:给定一个有限的实数集合,训练一个模型来最小化下列方程: 并且满足下列约束条件: 2.算法过程说明 从该序列的首元素往后观察,一旦出现乱序现象停止该轮 ...

  7. Spark机器学习(3):保序回归算法

    保序回归即给定了一个无序的数字序列,通过修改其中元素的值,得到一个非递减的数字序列,要求是使得误差(预测值和实际值差的平方)最小.比如在动物身上实验某种药物,使用了不同的剂量,按理说剂量越大,有效的比 ...

  8. bzoj 4709 [Jsoi2011]柠檬——单调栈二分处理决策单调性

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4709 题解:https://blog.csdn.net/neither_nor/articl ...

  9. Spark Mllib里如何采用保序回归做回归分析(图文详解)

    不多说,直接上干货! 相比于决策树,保序回归的应用范围没有决策树算法那么广泛. 特别在数据处理较为庞大的时候,采用保序回归做回归分析,可以极大地节省资源,从而提高计算效率. 保序回归的思想,是对数据进 ...

  10. 51NOD 1962 区间计数 单调栈+二分 / 线段树+扫描线

     区间计数   基准时间限制:1.5 秒 空间限制:262144 KB 分值: 80   两个数列 {An} , {Bn} ,请求出Ans, Ans定义如下: Ans:=Σni=1Σnj=i[max{ ...

随机推荐

  1. golang常用库包:redis操作库go-redis使用(01)-Redis数据类型简介和连接Redis的几种方式

    第一篇:go-redis使用,介绍Redis基本数据结构和其他特性,以及 go-redis 连接到Redis(本篇) https://www.cnblogs.com/jiujuan/p/1720716 ...

  2. VS Code实现SSH远程开发

    最近收获一台新台式机,但是个人主要还是使用自己的笔记本,用了几天远程控制,感觉各种不方便,最终决定配置一下VS Code实现SSH远程开发,特此记录. 首先介绍一下环境,控制端是Windows 11, ...

  3. 统信UOS系统开发笔记(五):安装QtCreator开发IDE中的中文输入环境Fcitx输入法

    前言   中文输入法,QtCreator中无法输入中文也是ubuntu中一个常规问题,在国产银河麒麟系统中也有此问题(PS:最终无法结局,用文本自行贴),国产UOS也有此问题,本片要解决此问题,主要是 ...

  4. Html飞机大战(十一): 飞机撞毁爆炸

    好家伙,这篇写英雄撞机爆炸   我们先把子弹销毁弄上去 子弹穿过敌机,敌机爆炸后消失,子弹同样也应该销毁,(当然后续会考虑穿甲弹)   然后我们还要把主角碰撞爆炸检测也加上去   因为他们共用一个思路 ...

  5. WPF 应用迁移到 Electron 框架过程记录

    前一段时间我用 WPF 开发了一个查看 emoji 表情的小工具 https://github.com/he55/EmojiViewer ,由于最近我使用 macOS 系统比较多,我想能在 macOS ...

  6. JS案例-网页轮播图

    鼠标经过轮播图模块,左右按钮提示,离开隐藏左右按钮 点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理 图片播放的同时,下面小圆圈模块跟随一起变化 点击小圆圈,可以播放相应图片 鼠标不经过轮播 ...

  7. Zabbix与乐维监控对比分析(五)——可视化篇

    前面我们详细介绍了Zabbix与乐维监控的架构与性能.Agent管理.自动发现.权限管理.对象管理.告警管理方面的对比分析,相信大家对二者的对比分析有了相对深入的了解,接下来我们将对二者的可视化功能进 ...

  8. be动词 系动词 连缀动词 Linking Verb

    be动词 系动词 连缀动词 Linking Verb be 原型 am 第一人称单数形式 is 第三人称单数形式 are 第二人称单数和复数形式 been 过去分词 being 现在分词 was 第一 ...

  9. Mysql查询数据量大小

    --按实例 SELECT CONCAT(round(sum(DATA_LENGTH/1024/1024/1024),2),"GB") as datazise FROM inform ...

  10. Android 8.0 Only fullscreen activities can request orientation解决方法

    原文:Android 8.0 Only fullscreen activities can request orientation解决方法 | Stars-One的杂货小窝 公司的项目坑太多,现在适配 ...