洛谷P1438 无聊的数列 (线段树+差分)
变了个花样,在l~r区间加上一个等差数列,等差数列的显著特点就是公差d,我们容易想到用线段树维护差分数组,在l位置加上k,在l+1~r位置加上d,最后在r+1位置减去k+(l-r)*d,这样就是在差分数组上操作,利用线段树打标记容易实现。
最后对于每个查询的位置t,查询1~t的区间和就是t位置上的数值。
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; #define ll long long int data[N]; struct node{ int l,r; ll sum,tag; }t[N<<2]; void pushup(int k){ t[k].sum=t[k<<1].sum+t[k<<1|1].sum; } void build(int k,int l,int r){ t[k].r=r,t[k].l=l; if(l==r) { t[k].sum=data[t[k].l]; return ; } int mid=(l+r)>>1; build(k<<1,l,mid);build(k<<1|1,mid+1,r); pushup(k); } void rev(int k,int x){ t[k].tag+=x; t[k].sum+=(t[k].r-t[k].l+1)*x; } void pushdown(int k){ rev(k<<1,t[k].tag);rev(k<<1|1,t[k].tag); t[k].tag=0; } void change(int k,int l,int r,ll x){ if(t[k].l>=l && t[k].r<=r){ t[k].tag+=x,t[k].sum+=(t[k].r-t[k].l+1)*x; return ; } int mid=(t[k].l+t[k].r)>>1; pushdown(k); if(l<=mid) change(k<<1,l,r,x); if(r>mid) change(k<<1|1,l,r,x); pushup(k); } ll query(int k,int l,int r){ if(t[k].l>=l && t[k].r<=r) return t[k].sum; int mid=(t[k].l+t[k].r)>>1; pushdown(k); ll ans=0; if(l<=mid) ans+=query(k<<1,l,r); if(r>mid) ans+=query(k<<1|1,l,r); return ans; } int main(){ int n,m,opt,l,r,k,d,t; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&data[i]); for(int i=n;i>1;i--) data[i]=data[i]-data[i-1];//差分数组 build(1,1,n); while(m--){ scanf("%d",&opt); if(opt==1){ scanf("%d%d%d%d",&l,&r,&k,&d); change(1,l,l,k); if(l+1<=r) change(1,l+1,r,d); if(r+1<=n) change(1,r+1,r+1,-(k+(r-l)*d));//注意加判断 } else{ scanf("%d",&t); cout<<query(1,1,t)<<endl; } } }
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探