原题链接

首先,我们考虑用差分解决问题。

用 \(x_i\) 表示原数列,\(a_i = x_i - x_{i-1}\)

那么,先普及一下差分:

如果我们只需要维护区间加值,单点求值的话,你会发现两个重要等式:

\[a_i = x_i - x_{i-1}
\]

\[\sum_{j=1}^i a_j = x_i
\]

我们每次修改 \(l,r\) 区间增加 \(k\) 的话,你会发现:

则 \(l+1,r\) 这一段,所有的 \(a_i\) 都是不变的。这是因为:

\[(x_i + k) - (x_{i-1} + k) = x_i - x_{i-1} = a_i
\]

那么对于 \(a_l\) 这个点,显然:

\[(x_l + k) - x_{l-1} = (x_l - x_{l-1}) + k = a_l + k
\]

对于 \(a_{r+1}\) 这个点,显然:

\[a_{r+1} - (a_r + k) = (a_{r+1} - a_r) - k = a_{r+1} - k
\]

这是正常的差分。

可是,我们现在加上了一个 等差数列 。由于等差数列的性质,显然每个点加上的值比前一个点多 \(d\).

所以, \(l+1 , r\) 这一段, \(a_i \gets a_i + d\) .

那么对于 \(a_l\) 这个点:

\[(x_l + k) - x_{l-1} = (x_l - x_{l-1}) + k = a_i + k
\]

对于 \(a_{r+1}\) 这个点:

\[x_{r+1} - (x_r + k + (r-l) \times d) = (x_{r+1} - x_r) - (k + (r-l) \times d) = a_{r+1} - (k + (r-l) \times d)
\]

下面我们考虑单点查询。

\[x_i = \sum_{j=1}^i a_j
\]

显然,我们用 线段树 维护 \(x\) 数组的区间修改和区间求和。

时间复杂度: \(O(n \log n + m \log n)\).

空间复杂度: \(O(n)\).

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std; typedef long long ll;
const int N=1e5+1;
#define L (i<<1)
#define R i<<1|1 inline ll read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
ll x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;} struct tree{
int l,r; ll tag;
ll sumi;
};
tree t[4*N];
int n,m,x[N]; //原数组
ll a[N]; //差分后的数组 inline void update(int i) {
t[i].sumi=t[L].sumi+t[R].sumi;
} //更新 inline void pass(int i,ll x) {
t[i].tag+=x;
t[i].sumi+=x*(t[i].r-t[i].l+1);
} inline void pushdown(int i) {
pass(L,t[i].tag);
pass(R,t[i].tag);
t[i].tag=0;
} //下传标记 inline void build_tree(int i,int l,int r) {
t[i].l=l; t[i].r=r;
if(l==r) {
t[i].sumi=a[l]; t[i].tag=0;
return;
} int mid=(l+r)>>1;
build_tree(L,l,mid);
build_tree(R,mid+1,r);
update(i);
} //建树 inline ll query(int i,int l,int r) {
if(l<=t[i].l && t[i].r<=r) return t[i].sumi;
int mid=(t[i].l+t[i].r)>>1; ll ans=0;
pushdown(i);
if(l<=mid) ans+=query(L,l,r);
if(r>mid) ans+=query(R,l,r);
return ans;
} //询问 inline void change(int i,int l,int r,int x) {
if(l<=t[i].l && t[i].r<=r) {
t[i].sumi+=x*(t[i].r-t[i].l+1);
t[i].tag+=x; return ;
} pushdown(i);
int mid=(t[i].l+t[i].r)>>1;
if(l<=mid) change(L,l,r,x);
if(r>mid) change(R,l,r,x);
update(i);
} //修改 int main(){
n=read(),m=read();
for(int i=1;i<=n;i++) x[i]=read();
for(int i=1;i<=n;i++) a[i]=ll(x[i]-x[i-1]);
// for(int i=1;i<=n;i++) printf("%d ",a[i]);
// putchar('\n');
build_tree(1,1,n);
while(m--) {
int opt=read();
ll l,r,k,d;
if(opt==1) {
l=read(),r=read(),k=read(),d=read();
change(1,l,l,k);
if(r>l) change(1,l+1,r,d);
if(r-n) change(1,r+1,r+1,-(k+(r-l)*d));
//维护
} else printf("%lld\n",query(1,1,read()));
}
return 0;
}

洛谷 P1438 无聊的数列 题解的更多相关文章

  1. 洛谷P1438 无聊的数列 [zkw线段树]

    题目传送门 无聊的数列 题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个数列{a[i]} ...

  2. 洛谷 P1438 无聊的数列

    题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个数列{a[i]},支持两种操作: 1.1 ...

  3. [洛谷P1438] 无聊的数列

    题目类型:差分,线段树 传送门:>Here< 题意:给出一个数列,每次给一个区间对应的加上一个等差数列,并询问某一个元素目前的值. 解题思路 所谓差分,我个人的理解就是用\(O(1)\)的 ...

  4. 洛谷P1438 无聊的数列 (线段树+差分)

    变了个花样,在l~r区间加上一个等差数列,等差数列的显著特点就是公差d,我们容易想到用线段树维护差分数组,在l位置加上k,在l+1~r位置加上d,最后在r+1位置减去k+(l-r)*d,这样就是在差分 ...

  5. Luogu P1438无聊的数列

    洛谷 P1438无聊的数列 题目链接 点这里! 题目描述 维护一个数列\(a_i\),支持两种操作: 给出一个长度等于 \(r-l+1\)的等差数列,首项为\(k\) 公差为\(d\) 并将它对应加到 ...

  6. 洛谷P1783 海滩防御 分析+题解代码

    洛谷P1783 海滩防御 分析+题解代码 题目描述: WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...

  7. P1438 无聊的数列 (差分+线段树)

    题目 P1438 无聊的数列 解析: 先考虑修改,用差分的基本思想,左端点加上首项\(k\),修改区间\((l,r]\)内每个数的差分数组都加上公差\(d\),最后的\(r+1\)再减去\(k+(r- ...

  8. P1438 无聊的数列

    P1438 无聊的数列 链接 分析: 等差数列可加,首项相加,公差相加. 代码: #include<cstdio> #include<algorithm> #include&l ...

  9. [luogu P1438] 无聊的数列

    [luogu P1438] 无聊的数列 题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个 ...

随机推荐

  1. 测试用例设计经典面试题之电梯、杯子、笔、桌子、洗衣机、椅子、ATM等

    测试用例设计经典面试题之电梯.杯子.笔.桌子.洗衣机.椅子.ATM等 1.测试项目:电梯 需求测试:查看电梯使用说明书.安全说明书等 界面测试:查看电梯外观 功能测试:测试电梯能否实现正常的上升和下降 ...

  2. 网购分期不还 N种恶果等着你

    N种恶果等着你" title="网购分期不还 N种恶果等着你"> 网购市场狂飙突进的发展,让每个人都享受到随时随地购物的乐趣,也在很大程度上推动商品之间的流通.目前 ...

  3. Ubuntu环境下的iptables的端口转发配置实例

    打开转发开关要让iptables的端口转发生效,首先需要打开转发开关方法一:临时打开,重启后失效$sudo su#echo 1 >/proc/sys/net/ipv4/ip_forward 方法 ...

  4. Vue源码之数据驱动(个人向)

    #1.大致流程 # 2.具体流程 数据驱动 New VUE Where:src/core/instance/index.js Do: 1.使用Function实现Vue类 2.调用_init 初始化V ...

  5. [ASP.NET Core 3框架揭秘] 服务承载系统[1]: 承载长时间运行的服务[上篇]

    借助.NET Core提供的承载(Hosting)系统,我们可以将任意一个或者多个长时间运行(Long-Running)的服务寄宿或者承载于托管进程中.ASP.NET Core应用仅仅是该承载系统的一 ...

  6. Docker实战之Kafka集群

    1. 概述 Apache Kafka 是一个快速.可扩展的.高吞吐.可容错的分布式发布订阅消息系统.其具有高吞吐量.内置分区.支持数据副本和容错的特性,适合在大规模消息处理场景中使用. 笔者之前在物联 ...

  7. 简单说 通过CSS的滤镜 实现 火焰效果

    说明 上次我们了解了一些css滤镜的基础知识, 简单说 CSS滤镜 filter属性 这次我们就来用css的滤镜实现一个 火焰的效果. 解释 要实现上面的火焰效果,我们先来了解一些必要的东西. 上次我 ...

  8. 关于使用fastjson出现的问题:com.alibaba.fastjson.JSONException: syntax error, expect {, actual string, pos 1, fastjson-version 1.2.44

    先说下需求:是从redis中根据keys批量获取数据集合,再通过fastjson转为对象集合 代码如下: 在postman测试后,出现错误如下: 刚开始以为是使用fstjson方法不对,后面先通过打断 ...

  9. excel排序技术记录

    问题: 给了我一个excel,要求以奖项和编码同时进行排序(奖项优先),但是单元格大小不一样,有数列都是合并了单元格的,同时编码的格式还不一样,有些是SMM-2-07,有些是2-07,所以根本无法进行 ...

  10. 【colab pytorch】使用tensorboardcolab可视化

    import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from ...