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

洛谷 P1438 无聊的数列 题解

题目链接:洛谷P1438 无聊的数列


哈喽,大家好,我们又见面啦!

今天我们来看 洛谷P1438 无聊的数列。

看到此题,我们首先考虑的就是暴力、树状数组和线段树(本题解并未讲解线段树)。

首先我们可以尝试暴力

暴力得分:91 分(还不错,开 O2 + 快读 + C++98)

#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
}
const int N=1e6+10;
int n=read(),m=read(),op,x,y,z,w,a[N];
signed main(){for(int i=1;i<=n;i++){a[i]=read();}while(m--){op=read();x=read();if(op==1){y=read();z=read();w=read();for(int i=x;i<=y;i++){a[i]+=z;z+=w;}}else{printf("%d\n",a[x]);}}return 0;
}

所以,此题我们不能单纯用暴力,我们要用树状数组!


首先,我们考虑一种比较慢点方法,循环单点修改。

代码很简单,得分:27 分(还没暴力快)。

#include<bits/stdc++.h>
#define int long long
#define lowbit(x) x&(-x)
using namespace std;
const int N=1e7+10;
int n,m,op,x,y,z,w,t,tr[N];
void upd(int i,int x){while(i<=n){tr[i]+=x;i+=lowbit(i);}
}
int getsum(int x){int ans=0;while(x>0){ans+=tr[x];x-=lowbit(x);}return ans;
}
signed main(){cin>>n>>m;for(int i=1;i<=n;i++){cin>>x;upd(i,x);}while(m--){cin>>op>>x;if(op==1){cin>>y>>z>>w;for(int i=x;i<=y;i++){upd(i,z);z+=w;}}else{cout<<getsum(x)-getsum(x-1)<<"\n";}}return 0;
}

于是,现在开始讲正解:

我们用树状数组 + 二阶差分。

下面是推导过程:

首先考虑公差为 0 的情况:

这种情况比较简单,我们可得:

d_l=d_l+K

d_{r+1}=d_{r+1}-K

然后,我们就可以得到:

d2_l=d2_l+K

d2_{l+1}=d2_{l+1}-K

d2_{r+1}=d2_{r+1}-K

d2_{r+2}=d2_{r+2}+K

还有一种情况,首项为 0 。相似,我们最终得到:

d2_{l+1}=d2_{l+1}+D

d2_{r+1}=-(r-l+1)\times D

d2_{r+2}=d2_{r+2}+(r-l)\times D

于是,结果就出来了:

d2_l+=k

d2_{l+1}+=D-K

d2_{r+1}+=-(r-l+1)\times D-K

d2_{r+2}+=(r-l) \times D+K

推出式子以后,代码就简单了。

100 分代码(最慢点 118 ms,还不错):

#include<bits/stdc++.h>
#define int long long
#define lowbit(x) x&(-x)
using namespace std;
const int N=1e7+10;
int n,m,op,x,y,z,w,a[N],b[N],tr[N],tr1[N];
void upd(int x,int y){int tmp=x;while(x<=n){tr[x]+=y;tr1[x]+=y*tmp;x+=lowbit(x);}
}
int getsum(int x){int tmp=x,ans=0;while(x){ans+=(tmp+1)*tr[x]-tr1[x];x-=lowbit(x);}return ans;
}
signed main(){cin>>n>>m;for(int i=1;i<=n;i++){cin>>a[i];b[i]=a[i]-a[i-1];upd(i,b[i]-b[i-1]);}while(m--){cin>>op;if(op==1){cin>>x>>y>>z>>w;upd(x,z);upd(x+1,w-z);upd(y+1,-z-(y-x+1)*w);upd(y+2,z+(y-x)*w);}else{cin>>x;cout<<getsum(x)<<"\n";}}return 0;
}

最后,我们略微看一下线段树的解法:

100 分代码如下(最慢点 81 ms,挺快的):

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
long long tr[N*4],tag[N*4],tag1[N*4];
void pu(long long p,long long l,long long r){if(tag[p]||tag1[p]){long long mid=(l+r)>>1;tr[p<<1]+=tag[p]*(mid-l+1)+tag1[p]*(mid-l+1)*(mid-l)/2;tag[p<<1]+=tag[p];tag1[p<<1]+=tag1[p];long long k1=tag[p]+tag1[p]*(mid-l+1);tr[p<<1|1]+=k1*(r-mid)+tag1[p]*(r-mid)*(r-mid-1)/2;tag[p<<1|1]+=k1;tag1[p<<1|1]+=tag1[p];tag[p]=tag1[p]=0;}
}
void upd(long long t,long long l,long long r,long long l1,long long r1,long long k,long long d){if(l1<=l&&r<=r1){long long cnt=r-l+1;long long tt=k+d*(l-l1);tr[t]+=tt*cnt + d*cnt*(cnt-1)/2;tag[t]+=tt;tag1[t]+=d;return;}pu(t,l,r);long long mid=(l+r)>>1;if(l1<=mid) upd(t<<1,l,mid,l1,r1,k,d);if(r1>mid) upd(t<<1|1,mid+1,r,l1,r1,k,d);tr[t]=tr[t<<1]+tr[t<<1|1];
}
long long qu(long long t,long long l,long long r,long long tmp){if(l==r) return tr[t];pu(t,l,r);long long mid=(l+r)>>1;if(tmp<=mid) return qu(t<<1,l,mid,tmp);else return qu(t<<1|1,mid+1,r,tmp);
}
long long n,m,a,ttt,l,r,k,d;
int main(){ios::sync_with_stdio(false);cin.tie(0);cin>>n>>m;for(long long i=1;i<=n;i++){cin>>ttt;upd(1,1,n,i,i,ttt,0);}while(m--){cin>>a;if(a==1){cin>>l>>r>>k>>d;upd(1,1,n,l,r,k,d);}else{cin>>l;cout<<qu(1,1,n,l)<<'\n';}}return 0;
}

于是,我们就做完了这道题。


后记:推导过程部分学习洛谷 ll_dio 的题解,在此鸣谢。

感谢大家阅读,我们下次再见(看在作者努力修改格式的面上,能不能给个关注啊)。

http://www.dtcms.com/a/490026.html

相关文章:

  • iOS混淆与IPA加固实战手记,如何构建苹果应用防反编译体系
  • 想抓PostgreSQL里的慢SQL?pg_stat_statements基础黑匣子和pg_stat_monitor时间窗,谁能帮你更准揪出性能小偷?
  • 把 iOS 26 的「Liquid Glass」带进 React Native
  • 基于物理信息的神经网络求解偏微分方程反问题的综合优化策略
  • 工地佩戴安全帽检测-目标检测数据集
  • 广东网站备案查询系统企业网站带后台
  • 知名的集团门户网站建设费用我要自学网网站建设
  • 2025 年 10 月科技前沿全景:从量子跃迁到生命重构的文明拐点
  • scene graph generation 用到的vg150数据集groundtruth数据预处理,展示和保存
  • 【Qt开发】多元素类控件(一)-> QListWidget
  • 【Mybatis从入门到入土】ResultMap映射、多表查询与缓存机制全解析
  • Springboot整合MinIO文件服务(windows版本)
  • HarmonyOS Next 项目完整学习指南
  • vscode离线下载依赖
  • Python 高效清理 Excel 空白行列:从原理到实战
  • 算法11.0
  • 工业级串口通信设计
  • 盐山网站建设广西网上办事大厅
  • 郑州高端网站制作团队大连本地网
  • Linux网络的应用层自定义协议
  • leetcode 2598 执行操作后的最大MEX
  • FFmpeg 基本API avio_read函数内部调用流程分析
  • 【计算机网络】HTTP协议核心知识梳理
  • 基于 MediaMTX 的微信小程序 Web 实时音视频实操方案
  • 《UDP网络编程完全指南:从套接字到高并发聊天室实战》
  • 关于 云服务器WindowsServer2016双击无法运行可执行程序 的解决方法
  • LeetCode每日一题——在区间范围内统计奇数数目
  • Linux内核架构浅谈43-Linux slab分配器:小内存块分配与内核对象缓存机制
  • 最好的免费发布网站wordpress 文章二维码
  • Spring Boot 3零基础教程,Spring Boot 日志格式,笔记18