当前位置: 首页 > news >正文

差分操作正确性证明

差分操作正确性证明

本文是作者因题目写差分写挂了后随手总结的。

定义

对于一个长度为 nnn 的数组 aaa,定义其差分数组为 ppp,且 ∀1≤i≤n,pi=ai−ai−1(a0=0)\forall 1\le i\le n,p_i=a_i-a_{i-1}(a_0=0)∀1in,pi=aiai1(a0=0)

转化回原数列

给些式子就懂了。

根据定义:
p1+p2+p3+⋯+pk=a1+(a2−a1)+(a3−a2)+⋯+(ak−ak−1)=akp_1+p_2+p_3+\cdots +p_k\\ =a_1+(a_2-a_1)+(a_3-a_2)+\cdots +(a_k-a_{k-1})\\ =a_k p1+p2+p3++pk=a1+(a2a1)+(a3a2)++(akak1)=ak
所以,ak=∑i=1kpia_k=\sum_{i=1}^k p_iak=i=1kpi
ak=∑i=1kpiak=∑i=1k−1pi+pkak=ak−1+pka_k=\sum_{i=1}^k p_i\\ a_k=\sum_{i=1}^{k-1}p_i+p_k\\ a_k=a_{k-1}+p_k ak=i=1kpiak=i=1k1pi+pkak=ak1+pk
另一种:
px=ax−ax−1ax=ax−1+pxp_x=a_x-a_{x-1}\\ a_x=a_{x-1}+p_x px=axax1ax=ax1+px
所以只要把 ppp 数组当作新的原数组,再将这个数组做个前缀和就 OK 了。

区间加法

假设需要将原数列的 [l,r][l,r][l,r] 全部加上 vvv。那么暴力是 O(n)O(n)O(n) 的,考虑用差分优化。

公式:pl←pl+v,pr+1←pr+1−vp_l\gets p_l+v,p_{r+1}\gets p_{r+1}-vplpl+v,pr+1pr+1v

证明:

显然 ∀1≤i≤l−1\forall 1\le i\le l-1∀1il1pip_ipi 是不变的。那么考虑转化的本质。

我们设 sis_isi 表示修改后的数组。即 si=si−1+pis_i=s_{i-1}+p_isi=si1+pi

∀l≤i≤rsi=∑j=1ipjsi=∑j=1i−1pj+pisi=si−1+pj\forall l\le i\le r\\ s_i=\sum_{j=1}^{i}p_j\\ s_i=\sum_{j=1}^{i-1}p_j+p_i\\ s_i=s_{i-1}+p_j lirsi=j=1ipjsi=j=1i1pj+pisi=si1+pj
那么在 [l,r][l,r][l,r] 区间里的数,在前缀和时就会被 sls_lsl 加上 vvv。而 [r+1,n][r+1,n][r+1,n] 里的数(不动的),则在 sr+1s_{r+1}sr+1 时减回来了,故值不变。

差分大概也就用到这些,再复杂点的就用线段树吧。

例题

给道例题:NOIP 2012 提高组 借教室。

代码:(差分+二分,时间复杂度 O(nlog⁡m)O(n\log m)O(nlogm)

#include<bits/stdc++.h>
using namespace std;
typedef long long ljl;
const int N=1e6+5;
int n,m;
ljl a[N],tp[N],sum[N],p[N];
struct R{int s,t;ljl d;
}r[N];
void addlr(int l,int r,int v)
{p[l]+=v;p[r+1]-=v;return;
}
bool check(int x)//check [1,x]
{for(int i=1;i<=n;++i)p[i]=tp[i];for(int i=1;i<=x;++i)addlr(r[i].s,r[i].t,-r[i].d);memset(sum,0,sizeof(sum));for(int i=1;i<=n;++i)sum[i]=p[i]+sum[i-1];for(int i=1;i<=n;++i)if(sum[i]<0)return 0;return 1;
}
int main(){ios::sync_with_stdio(0);cin>>n>>m;for(int i=1;i<=n;++i)cin>>a[i];for(int i=1;i<=m;++i)cin>>r[i].d>>r[i].s>>r[i].t;for(int i=1;i<=n;++i)tp[i]=a[i]-a[i-1];int l=0,r=m,mid=0;while(l<r){mid=(l+r+1)>>1;
//		cout<<l<<' '<<r<<' '<<mid<<' '<<check(mid)<<'\n';if(check(mid))l=mid;else r=mid-1;}if(l==m){cout<<"0\n";return 0;}cout<<"-1\n"<<l+1<<'\n';return 0;
}
http://www.dtcms.com/a/487540.html

相关文章:

  • 广西建设厅网证件查询郑州seo外包平台
  • 做个支付网站多少钱南通注册公司
  • 免费网站推广优化建设网站 法律责任
  • SpringAI 本地调用 Ollama
  • python 视频播放网站开发wordpress 预订插件
  • 公司网站维护重庆平台
  • 第5篇:自定义序列化器与反序列化器:突破默认逻辑
  • NSSCTF 理想国
  • 极速迁移:GitLab项目无缝转移实战手册
  • 视频解析转换耗时—OpenCV优化摸索路
  • 自己电脑做网站谁有网站推荐一下好
  • 组织架构树形选择组件使用说明(Vue3 + UniApp)
  • 响应式网站开发步骤去哪里学习建设网站
  • 网站建设与管理用什么软件有哪些内容南京外包公司
  • 电子商务网站规划的原则江苏省城乡建设网站
  • 项目学习总结:CAN总线、摄像头、STM32概述
  • Linux中在字符串中查找指定字符的第一次出现位置的汇编实现
  • 官方网站撰写策划书分布式移动网站开发技术
  • OpenPI源码分析
  • 智能化早诊:深度学习如何改变阿尔茨海默病的诊断未来
  • 把 AI“折”进纸里:基于折纸超材料的生成式电磁隐身设计,0.1mm 厚度实现 8-18GHz 全波段低可探测
  • 现在网站建设用什么语言开网店怎么找货源一件代发
  • 智能硬件使用小聆AI自定义MCP应用开发操作讲解
  • 一流的五屏网站建设企业网站建设 论文
  • 03、51 单片机介绍
  • PHP+MySQL开发实战:从数据库操作到SQL注入漏洞原理解析
  • 【MySQL】管理
  • 计算机视觉(opencv)——基于 MediaPipe 人体姿态检测
  • Spring ApplicationEventPublisher 异步处理与消息队列全面解析
  • 站长网站被跳转怎么办WordPress怎么去掉主题也没