题目传送门

题目大意:维护一个序列,维护区间加等差数列,单点查询的操作。

首先我们肯定是要用线段树来维护了,按照一般的思维局限,我选择了维护序列中的值,但是区间修改的时候由于公差的存在,所以区间修改有些难搞。后来又想分别维护\(k\)和\(d\),但是最终失败了。

正解十分巧妙,维护的是一个差分序列。如何维护?我们把\(l\)位置加上\(k\),把\([l,r)\)的位置加上\(d\),再把\(r+1\)的位置减去\(k+d*(r-l)\)。当查询的时候我们只要做一遍前缀和就好了。

然后??上一个线段树的区间修改+查询的板子就好了==。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #define maxn 100090
  4. using namespace std;
  5. typedef long long ll;
  6. int n,m;
  7. ll k,d,seq[maxn];
  8. struct SegmentTree{
  9. int l,r;
  10. ll val,lazy;
  11. }t[maxn*4];
  12. void build(int p,int l,int r)
  13. {
  14. t[p].l=l,t[p].r=r;
  15. if(l==r) return ;
  16. int mid=(l+r)>>1;
  17. build(p<<1,l,mid);
  18. build(p<<1|1,mid+1,r);
  19. }
  20. void update(int p)
  21. {
  22. if(!t[p].lazy||t[p].l==t[p].r) return ;
  23. t[p<<1].lazy+=t[p].lazy;
  24. t[p<<1|1].lazy+=t[p].lazy;
  25. t[p<<1].val+=t[p].lazy*(t[p<<1].r-t[p<<1].l+1);
  26. t[p<<1|1].val+=t[p].lazy*(t[p<<1|1].r-t[p<<1|1].l+1);
  27. t[p].lazy=0;
  28. }
  29. void change(int p,int l,int r,ll x)
  30. {
  31. update(p);
  32. if(t[p].l==l&&t[p].r==r)
  33. {
  34. t[p].val+=1ll*x*(r-l+1);
  35. t[p].lazy+=x;
  36. return ;
  37. }
  38. int mid=(t[p].l+t[p].r)>>1;
  39. if(l>mid) change(p<<1|1,l,r,x);
  40. else if(r<=mid) change(p<<1,l,r,x);
  41. else change(p<<1,l,mid,x),change(p<<1|1,mid+1,r,x);
  42. t[p].val=t[p<<1].val+t[p<<1|1].val;
  43. }
  44. ll ask(int p,int l,int r)
  45. {
  46. update(p);
  47. if(t[p].l==l&&t[p].r==r) return t[p].val;
  48. int mid=(t[p].l+t[p].r)>>1;
  49. if(l>mid) return ask(p<<1|1,l,r);
  50. else if(r<=mid) return ask(p<<1,l,r);
  51. else return ask(p<<1,l,mid)+ask(p<<1|1,mid+1,r);
  52. }
  53. int main()
  54. {
  55. scanf("%d%d",&n,&m);
  56. for(int i=1;i<=n;i++) scanf("%lld",&seq[i]);
  57. build(1,1,n);
  58. for(int i=1;i<=m;i++)
  59. {
  60. int op=0,p=0;
  61. scanf("%d",&op);
  62. if(op==1)
  63. {
  64. int l=0,r=0;
  65. scanf("%d%d%lld%lld",&l,&r,&k,&d);
  66. change(1,l,l,k);
  67. if(r>l) change(1,l+1,r,d);
  68. if(r!=n) change(1,r+1,r+1,-k-d*(r-l));
  69. }
  70. else if(op==2) scanf("%d",&p),printf("%lld\n",seq[p]+ask(1,1,p));
  71. }
  72. return 0;
  73. }

注意:防止RE,修改的时候在\([l+1,r)\)区间改的时候要注意是不是\(l=r\);以及在\(r+1\)修改的时候判断是不是右区间为\(n\)。

还是思维不要被僵化啊。

Luogu P1438无聊的序列【线段树/差分】By cellur925的更多相关文章

  1. P1438 无聊的数列 (线段树)

    题目链接 Solution 直接维护一个差分的线段树就好了. 其中线段树的节点代表 \(r\) 比 \(l\) 多多少. Code #include<bits/stdc++.h> #def ...

  2. Luogu P1607 庙会班车【线段树】By cellur925

    题目传送门 据说可以用贪心做?算了算了...我都不会贪.... 开始想的是用线段树,先建出一颗空树,然后输进区间操作后就维护最大值,显然开始我忽视了班车的容量以及可以有多组奶牛坐在一起的信息. 我们肯 ...

  3. [luogu P1438] 无聊的数列

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

  4. D - 小Z的加油店 线段树+差分+GCD

    D - 小Z的加油店 HYSBZ - 5028   这个题目是一个线段树+差分+GCD 推荐一个差分的博客:https://www.cnblogs.com/cjoierljl/p/8728110.ht ...

  5. bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1095 [题意] 给定一棵树,树上颜色或白或黑而且可以更改,多个询问求最远黑点之间的距离 ...

  6. 【BZOJ】1095: [ZJOI2007]Hide 捉迷藏 括号序列+线段树

    [题目]BZOJ 1095 [题意]给定n个黑白点的树,初始全为黑点,Q次操作翻转一个点的颜色,或询问最远的两个黑点的距离,\(n \leq 10^5,Q \leq 5*10^5\). [算法]括号序 ...

  7. luogu P2574 XOR的艺术 (线段树)

    luogu P2574 XOR的艺术 (线段树) 算是比较简单的线段树. 当区间修改时.\(1 xor 1 = 0,0 xor 1 = 1\)所以就是区间元素个数减去以前的\(1\)的个数就是现在\( ...

  8. 【原创】洛谷 LUOGU P3373 【模板】线段树2

    P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第 ...

  9. 【原创】洛谷 LUOGU P3372 【模板】线段树1

    P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别 ...

随机推荐

  1. 使用wepy 小程序授权点击取消授权失败的方案

    在wepy里使用进行小程序页面授权,里面包含了用户点击取消的重新授权方案: //auth.js /* * @Author: Porco_Mar * @Date: 2018-04-11 15:49:55 ...

  2. python的小知识点

    python中的变量的名字必须由字母.数字.下划线组成,并且不可以以数字开头. 字典的内容是键-值对,键必须是不可变的,比如字符,整数,浮点数,元组,列表不可以,因为列表可变.集合的元素不重复.字典和 ...

  3. 动态IP下群晖搭建DDNS服务

    转载地址:https://www.zimrilink.com/share/dsm_aliddns_server.html 通过阿里云API(php)搭建出DDNS动态域名解析服务器;不同的是本文的方法 ...

  4. IDEA 设置代码行宽度

    1.在File->settings->Editor->Code Style 2.在File->settings->Editor->Code Style->XM ...

  5. Android Studio的技巧

    1.快速添加add unimplements methods:  右键generate 2.快速添加try-catch:左边就有一个小电灯,然后可以选. 3.格式化OPTION + CMD + L ( ...

  6. MySQL活动期间制定月份注册用户下单情况_20161029

    在10.29到10.31号期间 10月新注册的用户订单金额满600元赠与优惠券 #3天内订单满600元且10月注册的用户订单明细 SELECT a.城市,a.用户ID,b.用户名称,DATE(b.注册 ...

  7. MySQL交叉表处理_20160923

    交叉表处理,在二维表中例如下面表 想把年月字段放到列字段,在sql中可以使用sum(if(条件,求和字段,null)) 函数来进行行列的转置 1.首先是上篇的年月字段在一列 SELECT city A ...

  8. 用CSS实现新闻轮播效果

    CSS: /* Make it a marquee */ .marquee { width: 450px;margin: 0 auto;overflow: hidden;white-space: no ...

  9. 【Lintcode】046.Majority Number

    题目: Given an array of integers, the majority number is the number that occurs more than half of the ...

  10. VirtualBox文件系统已满--磁盘扩容

    第1步:为virtualbox虚拟电脑扩容 进入命令行,以Windows系统为例 (特别注意空格和中文) 1.启动CMD命令行,进入VirtualBox的安装目录.如 运行:cmd C:\Users\ ...