洛谷 P1438 无聊的数列 题解
首先,我们考虑用差分解决问题。
用 \(x_i\) 表示原数列,\(a_i = x_i - x_{i-1}\)
那么,先普及一下差分:
如果我们只需要维护区间加值,单点求值的话,你会发现两个重要等式:
\]
\]
我们每次修改 \(l,r\) 区间增加 \(k\) 的话,你会发现:
则 \(l+1,r\) 这一段,所有的 \(a_i\) 都是不变的。这是因为:
\]
那么对于 \(a_l\) 这个点,显然:
\]
对于 \(a_{r+1}\) 这个点,显然:
\]
这是正常的差分。
可是,我们现在加上了一个 等差数列 。由于等差数列的性质,显然每个点加上的值比前一个点多 \(d\).
所以, \(l+1 , r\) 这一段, \(a_i \gets a_i + d\) .
那么对于 \(a_l\) 这个点:
\]
对于 \(a_{r+1}\) 这个点:
\]
下面我们考虑单点查询。
\]
显然,我们用 线段树 维护 \(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 无聊的数列 题解的更多相关文章
- 洛谷P1438 无聊的数列 [zkw线段树]
题目传送门 无聊的数列 题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个数列{a[i]} ...
- 洛谷 P1438 无聊的数列
题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个数列{a[i]},支持两种操作: 1.1 ...
- [洛谷P1438] 无聊的数列
题目类型:差分,线段树 传送门:>Here< 题意:给出一个数列,每次给一个区间对应的加上一个等差数列,并询问某一个元素目前的值. 解题思路 所谓差分,我个人的理解就是用\(O(1)\)的 ...
- 洛谷P1438 无聊的数列 (线段树+差分)
变了个花样,在l~r区间加上一个等差数列,等差数列的显著特点就是公差d,我们容易想到用线段树维护差分数组,在l位置加上k,在l+1~r位置加上d,最后在r+1位置减去k+(l-r)*d,这样就是在差分 ...
- Luogu P1438无聊的数列
洛谷 P1438无聊的数列 题目链接 点这里! 题目描述 维护一个数列\(a_i\),支持两种操作: 给出一个长度等于 \(r-l+1\)的等差数列,首项为\(k\) 公差为\(d\) 并将它对应加到 ...
- 洛谷P1783 海滩防御 分析+题解代码
洛谷P1783 海滩防御 分析+题解代码 题目描述: WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...
- P1438 无聊的数列 (差分+线段树)
题目 P1438 无聊的数列 解析: 先考虑修改,用差分的基本思想,左端点加上首项\(k\),修改区间\((l,r]\)内每个数的差分数组都加上公差\(d\),最后的\(r+1\)再减去\(k+(r- ...
- P1438 无聊的数列
P1438 无聊的数列 链接 分析: 等差数列可加,首项相加,公差相加. 代码: #include<cstdio> #include<algorithm> #include&l ...
- [luogu P1438] 无聊的数列
[luogu P1438] 无聊的数列 题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个 ...
随机推荐
- fastcgi_param详解
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;#脚本文件请求的路径 fastcgi_param QUERY_STRI ...
- Jprofile解析dump文件使用详解
1 Jprofile简介 官网 下载对应的系统版本即可 性能查看工具JProfiler,可用于查看java执行效率,查看线程状态,查看内存占用与内存对象,还可以分析dump日志. 2 功能简介 选择a ...
- 7——PHP选择结构
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...
- AF(操作者框架)系列(3)-创建第一个Actor的程序
这节课的内容,语言描述基本是无趣的,就是一个纯程序编写,直接上图了. 如果想做其他练习,可参考前面的文章: https://zhuanlan.zhihu.com/p/105133597 1. 新建一个 ...
- 简单的员工管理系统(Mysql+jdbc+Servlet+JSP)
员工管理系统 因为学业要求,需要完成一个过关检测,但是因为检测之前没有做好准备,且想到之前用mysql+jdbc+Struts2+bootstrap做成了一个ATM系统(主要有对数据的增删改查操作), ...
- 扫描神器nmap使用教程
总结 nmap -v 详细信息输出nmap -p 指定端口nmap -iL 扫描文件中的ipnmap -exclude 不扫描某些ipnmap -Pn 使用ping扫描,显式地关闭端口扫描,用于主机发 ...
- 关于AJAX方法
ajax的方法每次都记不住这次特意找了资料做了归总: 在这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数, ...
- Kali虚拟机的扩容经历
Kali虚拟机的扩容经历 0x01 起因 更新了一下软件包,竟然提示我空间不足. 升级了 687 个软件包,新安装了 82 个软件包,要卸载 0 个软件包,有 8 个软件包未被升级. 需要下载 1,5 ...
- 使用HBuilder开发移动APP:ajax调用接口数据
既然要做APP,与接口交互式少不了的,除非只是想做一个纯静态的APP.所以html5+的环境准备好后,我最先开始研究的就是如何与接口交互. 使用HBuilder新建示例教程后,里面会有一个ajax(网 ...
- 原生js中的常用方法的写法
1.js深度克隆的方法 //第一种 function deepClone(obj){ var str,newObj = obj instanceof Array? [] : {}; if(typeof ...