原文链接http://www.cnblogs.com/zhouzhendong/p/9031130.html

题目传送门 - LOJ#2512

题目传送门 - 洛谷P4458

题目传送门 - BZOJ5291

推荐LOJ和洛谷,题面质量好,而且不卡常数。

BZOJ题面烂,而且要卡那么一点点常数。

题意

  有一条长度为$n$的链$\forall 1≤i<n$,点$i$与点$i+1$之间有一条边的无向图),每个点有一个整数权值,第$i$个点的权值是$a_i$​​。现在有$m$个操作,每个操作如下:

  操作 1(修改):给定链上两个节点$u$、$v$和一个整数$d$,表示将链上$u$到$v$唯一的简单路径上每个点权值都加上$d$。

  操作 2(询问):给定两个正整数$L$、$R$,表示求链上所有节点个数大于等于$L$且小于等于$R$的简单路径节点权值和之和。由于答案很大,只用输出对质数$1000000007$取模的结果即可。

  一条节点个数为$k$的简单路径节点权值和为这条上所有$k$个节点(包括端点)的权值之和,而本题中要求是对所有满足要求的简单路径,求这一权值和的和。

  由于是无向图,路径也是无向的,即点$1$到点$2$的路径与点$2$到点$1$的路径是同一条,不要重复计算。

题解

  记$S_x[i]=\sum_{j=1}^{i} x[j]$,则我们现在来推一下式子。

  对于询问,我们要求的是:

$$\begin{align*}\sum_{i=L}^{R}\sum_{j=i}^{n}S_a[j]-S_a[j-i]&=\sum_{i=L}^{R}(\sum_{j=i}^{n}S_a[j]-\sum_{j=0}^{n-i}S_a[j])\\&=\sum_{i=L}^{R}(S_{S_a}[n]-S_{S_a}[i-1]-S_{S_a}[n-i])\\&=(R-L+1)S_{S_a}[n]-\sum_{i=L-1}^{R-1}S_{S_a}[i]-\sum_{n-R}^{n-L}S_{S_a}[i]\end{align*}$$

  只需要维护$S_{S_a}$的前缀和就可以了。

  考虑分类讨论区间加对$S_{S_a}$的贡献。

  在$L$~$R$区间加$v$的贡献为:

  记$len=R-L+1$,

  对于$L\leq i\leq R$,$S_{S_a}[i]=S_{S_a}[i]+\cfrac{(i-L+1)(i-L+2)}{2}v$。

  对于$i>R$,$S_{S_a}[i]=S_{S_a}[i]+\cfrac{len(len+1)}{2}v+len(i-R)v$。

  注意一下,对于修改,$L$和$R$可能是$L>R$的,我这里默认了$L\leq R$。

  于是这个区间加对于$S_{S_a}$的贡献可以转化成一个关于$i$的二次函数。

  可以用线段树来维护。

  在BZOJ上面,略微卡一点常数。建议在标记下传的时候,如果三个标记都为$0$就直接退出。

题解参考了:https://blog.csdn.net/cdsszjj/article/details/80286084

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. const int N=200005;
  5. const LL mod=1e9+7;
  6. int n,m,a[N];
  7. LL cv1[N],cv2[N];
  8. struct Seg{
  9. LL v,v0,v1,v2;
  10. LL s0,s1,s2;
  11. }t[N<<2];
  12. void build(int rt,int L,int R){
  13. t[rt].v0=t[rt].v1=t[rt].v2=0;
  14. t[rt].s0=R-L+1;
  15. if (L>0){
  16. t[rt].s1=(cv1[R]-cv1[L-1]+mod)%mod;
  17. t[rt].s2=(cv2[R]-cv2[L-1]+mod)%mod;
  18. }
  19. else
  20. t[rt].s1=cv1[R],t[rt].s2=cv2[R];
  21. if (L==R){
  22. t[rt].v=a[L];
  23. return;
  24. }
  25. int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
  26. build(ls,L,mid);
  27. build(rs,mid+1,R);
  28. t[rt].v=(t[ls].v+t[rs].v)%mod;
  29. }
  30. void addrt(int rt,LL d0,LL d1,LL d2){
  31. t[rt].v=(t[rt].v+d0*t[rt].s0+d1*t[rt].s1+d2*t[rt].s2)%mod;
  32. t[rt].v0=t[rt].v0+d0;
  33. t[rt].v1=t[rt].v1+d1;
  34. t[rt].v2=t[rt].v2+d2;
  35. if (t[rt].v0>=mod)t[rt].v0-=mod;
  36. if (t[rt].v1>=mod)t[rt].v1-=mod;
  37. if (t[rt].v2>=mod)t[rt].v2-=mod;
  38. }
  39. void pushdown(int rt){
  40. if (!t[rt].v0&&!t[rt].v1&&!t[rt].v2)
  41. return;
  42. int ls=rt<<1,rs=ls|1;
  43. addrt(ls,t[rt].v0,t[rt].v1,t[rt].v2);
  44. addrt(rs,t[rt].v0,t[rt].v1,t[rt].v2);
  45. t[rt].v0=t[rt].v1=t[rt].v2=0;
  46. }
  47. void update(int rt,int L,int R,int xL,int xR,LL d0,LL d1,LL d2){
  48. if (xL>xR)
  49. return;
  50. if (xL<=L&&R<=xR){
  51. addrt(rt,d0,d1,d2);
  52. return;
  53. }
  54. int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
  55. pushdown(rt);
  56. if (xR<=mid)
  57. update(ls,L,mid,xL,xR,d0,d1,d2);
  58. else if (xL>mid)
  59. update(rs,mid+1,R,xL,xR,d0,d1,d2);
  60. else {
  61. update(ls,L,mid,xL,mid,d0,d1,d2);
  62. update(rs,mid+1,R,mid+1,xR,d0,d1,d2);
  63. }
  64. t[rt].v=(t[ls].v+t[rs].v)%mod;
  65. }
  66. LL query(int rt,int L,int R,int xL,int xR){
  67. if (xL>xR)
  68. return 0;
  69. if (xL<=L&&R<=xR)
  70. return t[rt].v;
  71. int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
  72. pushdown(rt);
  73. if (xR<=mid)
  74. return query(ls,L,mid,xL,xR);
  75. else if (xL>mid)
  76. return query(rs,mid+1,R,xL,xR);
  77. else
  78. return (query(ls,L,mid,xL,xR)+query(rs,mid+1,R,xL,xR))%mod;
  79. }
  80. int main(){
  81. scanf("%d%d",&n,&m);
  82. for (int i=1;i<=n;i++){
  83. cv1[i]=(cv1[i-1]+i)%mod;
  84. cv2[i]=(cv2[i-1]+1LL*i*i)%mod;
  85. }
  86. for (int i=1;i<=n;i++)
  87. scanf("%d",&a[i]),a[i]=(a[i]+a[i-1])%mod;
  88. for (int i=1;i<=n;i++)
  89. a[i]=(a[i]+a[i-1])%mod;
  90. build(1,1,n);
  91. for (int i=1;i<=m;i++){
  92. int opt,L,R;
  93. LL v;
  94. scanf("%d%d%d",&opt,&L,&R);
  95. if (L>R)
  96. swap(L,R);
  97. if (opt==2){
  98. L=max(L,1);
  99. LL s1=query(1,1,n,n,n)*(R-L+1)%mod;
  100. LL s2=query(1,1,n,max(L-1,1),R-1);
  101. LL s3=query(1,1,n,max(n-R,1),n-L);
  102. printf("%lld\n",(s1-s2-s3+mod+mod+mod)%mod);
  103. }
  104. else {
  105. scanf("%lld",&v);
  106. LL len=R-L+1,iv2=500000004,vv=v*iv2%mod;
  107. update(1,1,n,L,R,vv*(L-1)%mod*(L-2)%mod,vv*(3-2*L+mod)%mod,vv);
  108. update(1,1,n,R+1,n,((len*(len+1)/2%mod*v-len*v%mod*R)%mod+mod)%mod,v*len%mod,0);
  109. }
  110. }
  111. return 0;
  112. }

  

BZOJ5291/洛谷P4458/LOJ#2512 [Bjoi2018]链上二次求和 线段树的更多相关文章

  1. 洛谷P4458 /loj#2512.[BJOI2018]链上二次求和(线段树)

    题面 传送门(loj) 传送门(洛谷) 题解 我果然是人傻常数大的典型啊-- 题解在这儿 //minamoto #include<bits/stdc++.h> #define R regi ...

  2. [BZOJ5291][BJOI2018]链上二次求和(线段树)

    感觉自己做的麻烦了,但常数似乎不算差.(只是Luogu最慢的点不到2s本地要跑10+s) 感觉我的想法是最自然的,但不明白为什么网上似乎找不到这种做法.(不过当然所有的做法都是分类大讨论,而我的方法手 ...

  3. 【BZOJ5291】[BJOI2018]链上二次求和(线段树)

    [BZOJ5291][BJOI2018]链上二次求和(线段树) 题面 BZOJ 洛谷 题解 考虑一次询问\([l,r]\)的答案.其中\(S\)表示前缀和 \(\displaystyle \sum_{ ...

  4. BZOJ5291 BJOI2018链上二次求和(线段树)

    用线段树对每种长度的区间维护权值和. 考虑区间[l,r]+1对长度为k的区间的贡献,显然其为Σk-max(0,k-i)-max(0,k-(n-i+1)) (i=l~r). 大力展开讨论.首先变成Σk- ...

  5. bzoj 5291: [Bjoi2018]链上二次求和

    Description 有一条长度为n的链(1≤i<n,点i与点i+1之间有一条边的无向图),每个点有一个整数权值,第i个点的权值是 a_i.现在有m个操作,每个操作如下: 操作1(修改):给定 ...

  6. 2018.01.04 bzoj5291: [Bjoi2018]链上二次求和(线段树)

    传送门 线段树基础题. 题意:给出一个序列,要求支持区间加,查询序列中所有满足区间长度在[L,R][L,R][L,R]之间的区间的权值之和(区间的权值即区间内所有数的和). 想题555分钟,写题202 ...

  7. loj2512 [BJOI2018]链上二次求和

    传送门 分析 咕咕咕 代码 #include<iostream> #include<cstdio> #include<cstring> #include<st ...

  8. 「BJOI2018」链上二次求和

    「BJOI2018」链上二次求和 https://loj.ac/problem/2512 我说今天上午写博客吧.怕自己写一上午,就决定先写道题. 然后我就调了一上午线段树. 花了2h找到lazy标记没 ...

  9. 洛谷P4459/loj#2511 [BJOI2018]双人猜数游戏(博弈论)

    题面 传送门(loj) 传送门(洛谷) 题解 所以博弈论的本质就是爆搜么-- 题解 //minamoto #include<bits/stdc++.h> #define R registe ...

随机推荐

  1. configure.*和Makefile.*之间的关系

    现在很多项目都在使用GUI编译器,Kdevelop\Eclipse等等,诚然它给我们提供了极大地便利,但我们仍需要简单了解编译的过程.本文旨在简单叙述由源码(*.cpp & *.h)经过编译得 ...

  2. 解决访问swaggerUI接口文档显示basic-error-controler问题

    问题描述 使用swagger生成接口文档后,访问http://localhost:8888/swagger-ui.html#/,显示如下: 有些强迫症的我,感觉看起来很不舒服,结果百度了好久,找到解决 ...

  3. 获取ScrollView ListView的当前位置的百分比

    找不到官方的API,就自己写了一下,下面是自己写的函数 --获取滚动层当前位置的百分比 function GetScrollViewPercent(scrollView) if scrollView ...

  4. python-模块入门

    一.模块介绍 模块:模块就是一系列功能的集合体 模块有三种来源: 1.内置模块   2.第三方的模块   3.自定义模块 模块的格式: 1使用python编写的.py文件   2.已被编译为共享库或D ...

  5. 小甜点,RecyclerView 之 ItemDecoration 讲解及高级特性实践

    本篇文章摘自微信公众号 guolin_blog (郭霖)独家发布 毫无疑问,RecyclerView 是现在 Android 世界中最重要的系统组件之一,它的出现就是为了高效代替 ListView 和 ...

  6. linq基本操作

    一.Linq有两种语法: 1.  方法语法 2.  查询语法 下面举个例子看看这两种方法的区别 比如现在有一个学生类 public class student { public string user ...

  7. js——this

    每个函数的this是在调用时绑定的,完全取决于函数的调用位置 1. 绑定规则总结 一般情况下,按下列顺序从下至上来判断this的绑定对象(绑定的优先级从下至上递减) 默认:在严格模式下绑定到undef ...

  8. Oracle 之 外部表

    一.外部表概述 外部表只能在Oracle 9i 之后来使用.简单地说,外部表,是指不存在于数据库中的表. 通过向Oracle 提供描述外部表的元数据,我们可以把一个操作系统文件当成一个只读的数 据库表 ...

  9. Weblogic12c 单节点安装

    第一节weblogic12c 的安装   WebLogic除了包括WebLogic Server服务器之外,还包括一些围绕WebLogic的产品,习惯上我们说的WebLogic是指WebLogic S ...

  10. Socket网络编程(三)

    TCP协议网络通讯案例(http协议) 1.创建TcpServer(tcp服务端) package com.cppdy.tcp; import java.io.IOException; import ...