题面

传送门(loj)

传送门(洛谷)

题解

我果然是人傻常数大的典型啊……

题解在这儿

//minamoto
#include<bits/stdc++.h>
#define R register
#define ls (p<<1)
#define rs (p<<1|1)
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int K=-1,Z=0;
inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
void print(R int x){
if(K>1<<20)Ot();if(x<0)sr[++K]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++K]=z[Z],--Z);sr[++K]='\n';
}
const int N=2e5+5,P=1e9+7,inv2=500000004,inv6=166666668;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
return res;
}
struct node{int l,r,a,b,sum[2];}tr[N<<2];
int a[N],n,m;
inline int f(R int x){return 1ll*x*(x+1)%P*((x<<1ll)+1)%P*inv6%P;}
void ppd(int p,int a,int b){
int sz=tr[p].r-tr[p].l;
tr[p].sum[0]=add(tr[p].sum[0],1ll*add(mul(2,a),mul(b,sz))*(sz+1)%P*inv2%P);
tr[p].sum[1]=add(tr[p].sum[1],1ll*a*(tr[p].l+tr[p].r)%P*(sz+1)%P*inv2%P);
tr[p].sum[1]=add(tr[p].sum[1],1ll*tr[p].l*b%P*sz%P*(sz+1)%P*inv2%P);
tr[p].sum[1]=add(tr[p].sum[1],mul(b,f(sz)));
tr[p].a=add(tr[p].a,a),tr[p].b=add(tr[p].b,b);
}
void upd(int p){
tr[p].sum[0]=add(tr[ls].sum[0],tr[rs].sum[0]);
tr[p].sum[1]=add(tr[ls].sum[1],tr[rs].sum[1]);
}
void pd(int p){
int mid=(tr[p].l+tr[p].r)>>1;
ppd(ls,tr[p].a,tr[p].b);
ppd(rs,add(tr[p].a,mul(mid-tr[p].l+1,tr[p].b)),tr[p].b);
tr[p].a=tr[p].b=0;
}
void build(int p,int l,int r){
tr[p].l=l,tr[p].r=r;
if(l==r)return tr[p].sum[0]=a[l],tr[p].sum[1]=mul(l,a[l]),void();
int mid=(l+r)>>1;
build(ls,l,mid),build(rs,mid+1,r);
upd(p);
}
int query(int p,int ql,int qr,int id){
if(ql<=tr[p].l&&qr>=tr[p].r)return tr[p].sum[id];
int mid=(tr[p].l+tr[p].r)>>1;
if(tr[p].a||tr[p].b)pd(p);
int res=0;
if(ql<=mid)res=add(res,query(ls,ql,qr,id));
if(qr>mid)res=add(res,query(rs,ql,qr,id));
return res;
}
void update(int p,int l,int r,int a,int b){
if(l==tr[p].l&&r==tr[p].r)return ppd(p,a,b);
if(tr[p].a||tr[p].b)pd(p);
int mid=(tr[p].l+tr[p].r)>>1;
if(r<=mid)update(ls,l,r,a,b);
else if(l>mid)update(rs,l,r,a,b);
else update(ls,l,mid,a,b),update(rs,mid+1,r,add(a,mul(b,mid+1-l)),b);
upd(p);
}
int calc(int x){
if(!x)return 0;
int res=0;
res=add(res,mul(query(1,x,n,0),x));
if(x!=n)res=add(res,P-mul(query(1,1,n-x,0),x));
if(x!=1)res=add(res,query(1,1,x-1,1));
res=add(res,P-add(mul(n,query(1,n-x+1,n,0)),P-query(1,n-x+1,n,1)));
return res;
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();
fp(i,1,n)a[i]=read(),a[i]=add(a[i],a[i-1]);
build(1,1,n);
int op,l,r,d;
while(m--){
op=read(),l=read(),r=read();
if(op==1){
d=read();if(l>r)swap(l,r);
update(1,l,r,d,d);
if(r<n)update(1,r+1,n,mul(d,r-l+1),0);
}else print(dec(calc(r),calc(l-1)));
}
return Ot(),0;
}

洛谷P4458 /loj#2512.[BJOI2018]链上二次求和(线段树)的更多相关文章

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

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

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

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

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

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

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

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

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

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

  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. Eclipse maven工程生命周期clean、compile、test、package

    1.清理. 编译 工程右键->Run As->Maven build... 清理.编译操作控制台信息输出: 2.测试  同清理.编译,goals改成test 3.打包  同清理.编译,go ...

  2. 搭建J2EE开发平台-Eclipse+MySql+tomcat

    搭建J2EE开发平台-Eclipse+MySql+tomcat 分类: ·Java 2010-10-10 15:45 2596人阅读 评论(3) 收藏 举报 mysql平台eclipsetomcatj ...

  3. 用Golang为Python编写模块

    Go里面需要显示的引入C模块, 让编译器支持生成动态链接库, 并且在代码中可以使用C语言的数据类型,这个至关重要. Calling Go code from Python code 摘取一个最简单例子 ...

  4. 201671010127 2016—2017-2 通过一个小程序对Java的再认识。

    学习了将近四周的Java语言,对于Java语言,我也有了更进一步的理解,出于对Java语言的喜爱,我总是喜欢没事的时候,自己敲一些很简单的代码,一边学习Java语言,一边对比C语言,往往可以帮助我们更 ...

  5. SQL2005 异常处理机制(Begin try Begin Catch)

    将可能会出错的sql 写在begin try...end try 之间,若出错,刚程序就跳到紧接着的begin try...end try 的beign catch...end catch中,执行be ...

  6. SQL中对数据截取替换

    REPLACE(要修改字段名,‘被替换的特定字符’,‘替换的字符’) 表结构和插入数据 CREATE DATABASE TEST GO USE TEST GO CREATE TABLE TestTab ...

  7. ArcGIS Engine中如何获取Map中已经选择的要素呢(转)

    ArcGIS Engine中如何获取Map中已经选择的要素呢   1.使用IEnumFeturea对象获取map中的FeatureSelection,该方法可以获取所有图层的选择要素.IMap中的Fe ...

  8. Linux问题:开启网关

    1 开启网关 1.1 问题描述 虚拟机每次重启后,都需要利用 ifup eth0 来手动开启网关,否则获取到的IP地址为回环127.0.0.1 1.2 解决办法 修改ifcfg-eth0中 ONBOO ...

  9. ThreadStart方式实现多线程

    以ThreadStart方式实现多线程 3.1 使用ThreadStart委托 这 里先以一个例子体现一下多线程带来的好处,首先在Message类中建立一个方法ShowMessage(),里面显示了当 ...

  10. 运行maven build报错No goals have been specified for this build.

    运行maven报错: [ERROR] No goals have been specified for this build. You must specify a valid lifecycle p ...