QAQ一道线段树好题

题目大意:

给定一个有n个数的数列,共m种操作,有两种操作

\(1\ l\ r\ k\ d\)表示将\(a[l]\)~\(a[r]\)的数加一个以k为首相,d为公差

\(2\ x\)表示求\(a[x]\)是多少

QwQ又是一道不会的题

暴力修改肯定会T飞

如果可以用线段树进行区间修改呢??



我们考虑,对于一段区间\([l,r]\),我们只需要记录它的区间的首相和公差,就能将这个标记下传了

QwQ哇,那可以只使用这个线段树进行一个标记下传了(所以没有up函数)

这里展示一下pushdown的部分

\(f[root].d\)表示公差,\(f[root].first\)表示首相

  1. void pushdown(int root,int l,int r)
  2. {
  3. if (f[root].d || f[root].first)
  4. {
  5. int mid = (l+r) >> 1;
  6. f[2*root].d+=f[root].d;
  7. f[2*root+1].d+=f[root].d;
  8. f[2*root].first+=f[root].first;
  9. f[2*root+1].first+=(f[root].first+(mid-l+1)*f[root].d);
  10. f[root].d=f[root].first=0;
  11. }
  12. }

因为,等差数列相加依然是等差数列,所以对于公差和首相,可以直接加

对一个区间的话\([l,r]\),\([l,mid]\)这部分可以直接进行加法,而对于\([mid+1,r]\)稍微操作一下,修改首相即可

求和什么的,也比较简单

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<cstdlib>
  7. #include<queue>
  8. #include<map>
  9. #include<vector>
  10. using namespace std;
  11. inline int read()
  12. {
  13. int x=0,f=1;char ch=getchar();
  14. while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
  15. while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  16. return x*f;
  17. }
  18. const int maxn = 100010;
  19. struct Node{
  20. int d,first;
  21. };
  22. Node f[4*maxn];
  23. Node add[4*maxn];
  24. int a[4*maxn];
  25. int n,m;
  26. void pushdown(int root,int l,int r)
  27. {
  28. if (f[root].d || f[root].first)
  29. {
  30. int mid = (l+r) >> 1;
  31. f[2*root].d+=f[root].d;
  32. f[2*root+1].d+=f[root].d;
  33. f[2*root].first+=f[root].first;
  34. f[2*root+1].first+=(f[root].first+(mid-l+1)*f[root].d);
  35. f[root].d=f[root].first=0;
  36. }
  37. }
  38. void update(int root,int l,int r,int x,int y,int first,int d)
  39. {
  40. if (x<=l && r<=y){
  41. f[root].d+=d;
  42. f[root].first+=(l-x)*d+first;
  43. return ;
  44. }
  45. pushdown(root,l,r);
  46. int mid = (l+r) >> 1;
  47. if (x<=mid) update(2*root,l,mid,x,y,first,d);
  48. if (y>mid) update(2*root+1,mid+1,r,x,y,first,d);
  49. }
  50. int query(int root,int l,int r,int pos)
  51. {
  52. if (l==r)
  53. {
  54. return a[l]+f[root].first;
  55. }
  56. pushdown(root,l,r);
  57. int mid = (l+r) >> 1;
  58. if (pos<=mid) return query(2*root,l,mid,pos);
  59. if (pos>mid) return query(2*root+1,mid+1,r,pos);
  60. }
  61. int main()
  62. {
  63. scanf("%d%d",&n,&m);
  64. for (int i=1;i<=n;i++) a[i]=read();
  65. for (int i=1;i<=m;i++)
  66. {
  67. int opt;
  68. opt=read();
  69. if (opt==1)
  70. {
  71. int l,r,k,d;
  72. l=read(),r=read(),k=read(),d=read();
  73. update(1,1,n,l,r,k,d);
  74. }
  75. else
  76. {
  77. int x=read();
  78. printf("%d\n",query(1,1,n,x));.
  79. }
  80. }
  81. return 0;
  82. }

luogu1438无聊的数列(区间加等差数列,求一个数的和)的更多相关文章

  1. [cdoj 1344]树状数组区间加等差数列

    题目链接:http://acm.uestc.edu.cn/#/problem/show/1344 区间加等差数列本质上就是区间修改区间查询,本来想用线段树做,结果这个题就是卡空间和时间……不得已学了区 ...

  2. LUOGU1438无聊的数列

    区间加等差数列单点查询 思路: 差分,通过树状数组修改,然后保存两个数组,一个存公差,一个存和 然后正常操作即可 在学校潦草写的很潦草啦 代码如下: #include<cstdio> #i ...

  3. Luogu1438 无聊的数列(单点查询)&&加强版(区间查询)

    题目链接:戳我 线段树中差分和前缀和的应用 其实对于加上等差数列的操作我们可以分成这样三步-- update(1,1,n,l,l,k); if(r>l) update(1,1,n,l+1,r,d ...

  4. [luogu1438]无聊的数列

    考虑令$b_{i}=a_{i+1}-a_{i}$,那么1操作相当于对L加上K,对(L,R]区间加上D,对R+1减去K+(R-L)*D,然后询问区间和即可 1 #include<bits/stdc ...

  5. [LuoguP1438]无聊的数列(差分+线段树/树状数组)

    \(Link\) \(\color{red}{\mathcal{Description}}\) 给你一个数列,要求支持单点查询\(and\)区间加等差数列. \(\color{red}{\mathca ...

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

    传送门 解题思路 区间加等差数列+单点询问,用差分+线段树解决,线段树里维护的就是差分数组,区间加等差数列相当于在差分序列中l位置处+首项的值,r+1位置处-末项的值,中间加公差的值,然后单点询问就相 ...

  7. [用CDQ分治解决区间加&区间求和]【习作】

    [前言] 作为一个什么数据结构都不会只会CDQ分治和分块的蒟蒻,面对区间加&区间求和这么难的问题,怎么可能会写线段树呢 于是,用CDQ分治解决区间加&区间求和这篇习作应运而生 [Par ...

  8. LOJ6283 数列分块入门 7 (分块 区间加/乘)题解

    题意:区间加,区间乘,单点询问 思路:假设一个点为a,那么他可以表示为m * a + sum,所以区间加就变为m * a + sum + sum2,区间乘变为m * m2 * a + sum * m2 ...

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

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

随机推荐

  1. IoT边缘,你究竟是何方神圣?

    摘要:IoT边缘扮演着纽带的作用,连接边缘和云,将边缘端的实时数据处理,云端的强大计算能力两者结合,创造无限的价值. 本文分享自华为云社区<IoT边缘如何实现海量IoT数据就地处理>,作者 ...

  2. HCNP Routing&Switching之动态路由协议IS-IS基础

    前文我们了解了OSPF的特殊区域相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15236330.html:今天我们来聊一聊另一动态路由协议IS-IS相 ...

  3. Linux--MySQL 日志管理、备份与恢复

    MySQL 日志管理.备份与恢复一.MySQL 日志管理二.数据库备份的重要性与分类  1.数据备份的重要性  2.从物理与逻辑的角度,备份分为  3.从数据库的备份策略角度,备份可分为三.常见的备份 ...

  4. noip模拟45

    A. 打表 首先注意这道题数组下标从 \(0\) 开始 可以找规律发现是 \(\displaystyle\frac{\sum |a_i-a _ {ans}|}{2^k}\) 那么严谨证明一下: 由于两 ...

  5. FastAPI 学习之路(一)fastapi--高性能web开发框架

    fastapi是高性能的web框架.他的主要特点是:- 快速编码- 减少人为bug- 直观- 简易- 具有交互式文档 - 高性能 - 基于API的开放标准 支持python 3.6版本. 安装 pip ...

  6. 对javaEE Tutorial上hello2的源码分析详解

    首先: java EE 上的hello2项目是一个部署在glass fish上的开发源码的java web项目,在终端通过命令行使用maven进行打包成.war文件,最后部署到相关的glass fis ...

  7. PHP中的“重载”是个啥?

    很多面试官在面试的时候都会问一些面向对象的问题,面向对象的三大特性中,多态最主要的实现方式就是方法的重载和重写.但是在PHP中,只有重写,并没有完全的重载能力的实现. 重写,子类重写父类方法. // ...

  8. 后期静态绑定在PHP中的使用

    什么叫后期静态绑定呢?其实我们在之前的文章PHP中的static中已经说过这个东西了.今天我们还是再次深入的理解一下这个概念. 首先,我们通过一段代码来引入后期静态绑定这一概念: class A { ...

  9. ThinkPHP5通过composer安装Workerman安装失败问题

    报错: topthink/think-worker v3.0.2 requires topthink/framework ^6 https://blog.csdn.net/Douz_lungfish/ ...

  10. AVS 通信模块之AVSConnectionManager

    AVSConnectionManager 类为客户端无缝地管理与AVS的连接 功能简介 失败时连接重试 允许后续重新连接 ping管理 AVS服务器断开时周期重连服务器 允许客户端完全启用或禁用连接管 ...