感觉自己做的麻烦了,但常数似乎不算差。(只是Luogu最慢的点不到2s本地要跑10+s)

感觉我的想法是最自然的,但不明白为什么网上似乎找不到这种做法。(不过当然所有的做法都是分类大讨论,而我的方法手算部分较为麻烦)

每次询问考虑每个位置的贡献,拆分成求所有长度<=R的区间的贡献次数和减去长度<L的区间贡献次数和。

分成两大类考虑,设当前考虑长度在[1,r]的所有区间,当前要计算数a[k]的贡献次数:

一: $2r\leq n$

  1.$k\leq r$ 观察所有包含k的长度不超过r的区间,发现答案为$1+2+...+i+i+i+...i=\frac{1}{2}[(2r+1)i-i^2]$

  2.$r<k<n-r+1$ 左右两边都可以延伸k的长度,于是答案为$1+2+...+r=\frac{r(r+1)}{2}$

  3.$k\geq n-r+1$ 和情况一类似,答案为$1+2+...+(n-i)+(n-i)+(n-i)+...=\frac{1}{2}[2nr-n^2-n+2r+(2n-2r+1)i-i^2]$

二:$2r>n$

  1.$k\leq n-r+1$观察发现和上面情况一是一样的:$\frac{1}{2}[(2r+1)i-i^2]$

  2.$n-r+1<k<n/2$

    答案为$1+2+...+i+i+...+i+(i-1)+(i-2)+...=\frac{1}{2}[2nr-n^2-r^2+r-n+(2n+n)i-2i^2]$

   $n/2\leq k<r$

    一波复杂的带入化简发现答案同上:$\frac{1}{2}[2nr-n^2-r^2+r-n+(2n+n)i-2i^2]$

  3.$k\geq r$ 观察发现和上面情况三是一样的:$\frac{1}{2}[2nr-n^2-n+2r+(2n-2r+1)i-i^2]$

于是分别维护$\sum a_i$,$\sum a_i*i$,$\sum a_i*i^2$即可。

 #include<cstdio>
#include<algorithm>
#define ls (x<<1)
#define rs (ls|1)
#define lson ls,L,mid
#define rson rs,mid+1,R
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=,mod=1e9+,inv2=(mod+)/,inv6=(mod+)/;
int n,m,op,l,r,x,a[N]; int rd(){
int x=; char ch=getchar(); bool f=;
while (ch<'' || ch>'') f|=(ch=='-'),ch=getchar();
while (ch>='' && ch<='') x=(x<<)+(x<<)+(ch^),ch=getchar();
return f ? -x : x;
} struct P{ int a[],tag; }v[N<<];
inline void inc(int &x,int y){ x+=y; (x>=mod)?x-=mod:; } P operator +(P a,P b){
inc(a.a[],b.a[]); inc(a.a[],b.a[]);
inc(a.a[],b.a[]); a.tag=; return a;
} int cal1(int x){ return 1ll*x*(x+)/%mod; }
int cal2(int x){ return 1ll*x*(x+)*(*x+)%mod*inv6%mod; } void put(int x,int L,int R,int k){
inc(v[x].a[],1ll*(R-L+)*k%mod);
inc(v[x].a[],1ll*(cal1(R)-cal1(L-)+mod)*k%mod);
inc(v[x].a[],1ll*(cal2(R)-cal2(L-)+mod)*k%mod);
inc(v[x].tag,k);
} void push(int x,int L,int R){
if (!v[x].tag) return;
int mid=(L+R)>>;
put(lson,v[x].tag); put(rson,v[x].tag); v[x].tag=;
} void build(int x,int L,int R){
if (L==R){
v[x].a[]=a[L]; v[x].a[]=1ll*a[L]*L%mod;
v[x].a[]=1ll*a[L]*L%mod*L%mod; return;
}
int mid=(L+R)>>;
build(lson); build(rson); v[x]=v[ls]+v[rs];
} void mdf(int x,int L,int R,int l,int r,int k){
if (L==l && r==R){ put(x,L,R,k); return; }
int mid=(L+R)>>; push(x,L,R);
if (r<=mid) mdf(lson,l,r,k);
else if (l>mid) mdf(rson,l,r,k);
else mdf(lson,l,mid,k),mdf(rson,mid+,r,k);
v[x]=v[ls]+v[rs];
} P que(int x,int L,int R,int l,int r){
if (L==l && r==R) return v[x];
int mid=(L+R)>>; push(x,L,R);
if (r<=mid) return que(lson,l,r);
else if (l>mid) return que(rson,l,r);
else return que(lson,l,mid)+que(rson,mid+,r);
} int Q1(int d,int r){
P t=que(,,n,,d);
return (1ll*t.a[]*(2ll*r+)%mod-t.a[]+mod)%mod*inv2%mod;
} int Q2(int d,int r){
if (d>n) return ;
P t=que(,,n,d,n);
return (((2ll*n*r-1ll*n*n-n+2ll*r)%mod*t.a[]%mod+(2ll*n-2ll*r+)%mod*t.a[]%mod-t.a[])%mod+mod)%mod*inv2%mod;
} int Q3(int L,int R,int r){
P t=que(,,n,L,R); return 1ll*r*(r+)/%mod*t.a[]%mod;
} int Q4(int L,int R,int r){
if (L>R) return ;
P t=que(,,n,L,R);
return (((2ll*n*r-1ll*n*n-1ll*r*r+r-n)%mod*t.a[]%mod+(2ll*n+)*t.a[]%mod-2ll*t.a[])%mod+mod)%mod*inv2%mod;
} int solve(int r){
if (!r) return ;
int L=min(r,n-r+),R=max(r,n-r+);
if (L==R) R++;
int r1=Q1(L,r),r2=Q2(R,r);
int r3=(L+<=R-)?((r<=n-r+)?Q3(L+,R-,r):Q4(L+,R-,r)):;
return (1ll*r1+r2+r3)%mod;
} int main(){
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
n=rd(); m=rd();
rep(i,,n) a[i]=rd();
build(,,n);
while (m--){
op=rd(); l=rd(); r=rd();
if (l>r) swap(l,r);
if (op==) x=rd(),mdf(,,n,l,r,x);
else printf("%d\n",(solve(r)-solve(l-)+mod)%mod);
}
return ;
}

[BZOJ5291][BJOI2018]链上二次求和(线段树)的更多相关文章

  1. BZOJ5291/洛谷P4458/LOJ#2512 [Bjoi2018]链上二次求和 线段树

    原文链接http://www.cnblogs.com/zhouzhendong/p/9031130.html 题目传送门 - LOJ#2512 题目传送门 - 洛谷P4458 题目传送门 - BZOJ ...

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

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

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

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

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

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

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

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

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

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

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

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

  8. 「BJOI2018」链上二次求和

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

  9. [bzoj5291]链上二次求和

    记$bi=b_{i-1}+ai$,$ci=c_{i-1}+bi$,那么答案就是$\sum_{i=l}^{r}\sum_{j=0}^{n-i}b_{j+i}-bj=(r-l+1)cn-\sum_{i=l ...

随机推荐

  1. 工具推荐:Backdoor-apk,安卓APK文件后门测试工具

    工具推荐:Backdoor-apk,安卓APK文件后门测试工具 Backdoor-apk可以看成是一个shell脚本程序,它简化了在Android APK文件中添加后门的过程.安全研究人员在使用该工具 ...

  2. django Rest Framework----APIView 执行流程 APIView 源码分析

    在django—CBV源码分析中,我们是分析的from django.views import View下的执行流程,这篇博客我们介绍django Rest Framework下的APIView的源码 ...

  3. Linux下获取和设置IP

    在Linux下获取关于IP和网关的操作:重点是对struct ifreq 的操作. 那么进入目录/usr/include/net/if.h下看查找struct ifreq结构体. /* Interfa ...

  4. python网络编程--线程锁(互斥锁Mutex)

    一:为什么需要线程锁 一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据,此时,如果2个线程同时要修改同一份数据,会出现什么状况? 很简单,假设你有A,B两 ...

  5. 虚拟机 SUSE Linux Enterprise Server 12 SP2 64

    下载地址:https://www.suse.com/zh-cn/products/server/download/ 下载以后使用虚拟机安装即可

  6. 程序设计分层思想和DAO设计模式的开发

    无论是一个应用程序项目还是一个Web项目,我们都可以按照分层思想进行程序设计.对于分层,当下最流行划分方式是:表现层+控制层+业务层+数据层.其中,业务层和数据层被统称为后台业务层,而表现层和控制层属 ...

  7. 课堂实验-模拟实现Sort

    课堂实验 模拟实现Linux下Sort -t : -k 2的功能.参考 Sort的实现. 代码如下: /** * Created by Administrator on 2017/5/20. */ i ...

  8. django model常用字段类型

    摘自 http://www.cnblogs.com/wt869054461/p/4014271.html V=models.AutoField(**options) #int:在Django代码内是自 ...

  9. Windows平台的rop exp编写

    摘抄自看雪 Windows的ROP与Linux的ROP并不相同,其实Linux下的应该叫做是ret2libc等等.Windows的ROP有明确的执行目标,比如开辟可执行内存然后拷贝shellcode, ...

  10. CCF CSP 201703-2 学生排队

    博客中的文章均为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201703-2 学生排队 问题描述 体育老师小明要将自己班上的学生按顺序排队.他首先让学生按学号从小到大的顺序排成一排, ...