Luogu P1438 无聊的数列
# 解题思路
这题还是有些恶心的,稍不注意就会 RE 或者是 WA。
我们先来看看题目中给出的要求:给定等差数列的公差和首项,在给定一个区间,给这个区间加上这个等差数列(逐项)。
emmmm,考虑一下给一个区间加了一个等差序列之后与原序列相比,有哪些改变,既然是加的等差数列,那每两相邻个数之间的差的变化是一样的,为题目中给出的公差。
那么也就可以想到用差分数组来做这道题。将原序列的变化搬到差分数组上之后,会发生如下的变化:
- 差分数组的第一个数肯定要加上 K。
- 差分数组的 (L,R](L,R] 这个区间内,每项都要加上 D。
- 差分数组的第 R+1 项要减去 K+D×(R−L)
值得注意的是,在发生后两种变化时要判断区间的类型,如果这个区间的右端点是 n,那么我们就不进行第三个变化,如果这个区间的左右端点相等,就不进行第二个变化。
那从上面来看的话,这个题就是用线段树维护差分数组,支持区间求和和区间加法。
我写线段树的时候写的懒标记在询问时忘记下传了,233,果然还是我太菜。
# 附上代码
给大家看看我奇丑无比自带超大常数的傻逼线段树
- #include <iostream>
- #include <cstring>
- #include <cstdio>
- using namespace std;
- const int maxn = 1e5+3;
- struct node {int l, r, sum, f;} tree[maxn << 2];
- int n, m, a[maxn], d[maxn], tot = 0;
- struct Segment {
- #define Lson (k << 1)
- #define Rson ((k << 1) | 1)
- void read(int &x) {
- x = 0; int f = 1; char c = getchar();
- while (c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
- while (c <= '9' && c >= '0') {x = x*10 + c-'0'; c = getchar();}
- x *= f;
- }
- void build(int k, int ll, int rr) {
- tree[k].l = ll, tree[k].r = rr;
- if(tree[k].l == tree[k].r) {
- tree[k].sum = 0;
- return ;
- }
- int mid = (tree[k].l + tree[k].r) >> 1;
- build(Lson, tree[k].l, mid);
- build(Rson, mid+1, tree[k].r);
- tree[k].sum = tree[Lson].sum + tree[Rson].sum;
- }
- void pushdown(int k) {
- tree[Lson].sum += tree[k].f * (tree[Lson].r - tree[Lson].l + 1);
- tree[Rson].sum += tree[k].f * (tree[Rson].r - tree[Rson].l + 1);
- tree[Lson].f += tree[k].f, tree[Rson].f += tree[k].f;
- tree[k].f = 0;
- }
- void update(int k, int L, int R, int num) {
- if(tree[k].l >= L && tree[k].r <= R) {
- tree[k].sum += (tree[k].r - tree[k].l + 1) * num;
- tree[k].f += num;
- return ;
- }
- if(tree[k].f) pushdown(k);
- int mid = (tree[k].l + tree[k].r) >> 1;
- if(L <= mid) update(Lson, L, R, num);
- if(R > mid) update(Rson, L, R, num);
- tree[k].sum = tree[Lson].sum + tree[Rson].sum;
- }
- int query(int k, int L, int R) {
- int ans = 0;
- if(tree[k].l >= L && tree[k].r <= R)
- return tree[k].sum;
- if(tree[k].f) pushdown(k);
- int mid = (tree[k].l + tree[k].r) >> 1;
- if(L <= mid) ans += query(Lson, L, R);
- if(R > mid) ans += query(Rson, L, R);
- return ans;
- }
- void init() {
- read(n), read(m);
- for(int i=1; i<=n; i++)
- read(a[i]);
- }
- void Query() {
- int opt, l, r, k, D;
- for(int i=1; i<=m; i++) {
- read(opt), read(l);
- if(opt == 1) {
- read(r), read(k), read(D);
- update(1, l, l, k);
- if(r != n) update(1, r+1, r+1, -(k+(r-l)*D));
- if(r > l) update(1, l+1, r, D);
- }
- else {
- printf("%d\n", a[l] + query(1, 1, l));
- }
- }
- }
- Segment () {
- init(), build(1, 1, n);
- Query();
- }
- }T;
- int main() {}
作者:Mystical-W
来源:http://www.cnblogs.com/bljfy
说明:客官~~您如果觉得写得好的话,记得给我点赞哦。如果要转载的请在合适的地方注明出处。谢
谢您的合作。您要是有什么有疑问的地方可以在下面给我评论。也可以直接私信我哦
声明:本作品由Mystical-W采用知识共享署名-非商业性使用-禁止演绎 4.0 国
际许可协议进行许可
来源:http://www.cnblogs.com/bljfy
说明:客官~~您如果觉得写得好的话,记得给我点赞哦。如果要转载的请在合适的地方注明出处。谢
谢您的合作。您要是有什么有疑问的地方可以在下面给我评论。也可以直接私信我哦
声明:本作品由Mystical-W采用知识共享署名-非商业性使用-禁止演绎 4.0 国
际许可协议进行许可
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· 深入理解Mybatis分库分表执行原理
· 使用 Dify + LLM 构建精确任务处理应用