loj2512 [BJOI2018]链上二次求和

传送门

分析

咕咕咕

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define int long long
const int mod = 1e9+7;
const int t = 5e8+4;
int n,m,p[200100],pp[200100],d[20000100],Ans,f1[200100],f2[200100];
int cola[20000100],colb[20000100],colc[20000100];
inline void build(int le,int ri,int wh){
    if(le==ri){
      d[wh]=pp[le]*2%mod;
      return;
    }
    int mid=(le+ri)>>1;
    build(le,mid,wh<<1);
    build(mid+1,ri,wh<<1|1);
    d[wh]=(d[wh<<1]+d[wh<<1|1])%mod;
}
inline int S(int le,int ri,int a,int b,int c){
    int res=c*(ri-le+1)%mod+b*((f1[ri]-(le?f1[le-1]:0)+mod)%mod)%mod
              +a*((f2[ri]-(le?f2[le-1]:0)+mod)%mod)%mod;
    return res%mod;
}
inline void pd(int wh,int le,int mid,int ri){
    int a=cola[wh],b=colb[wh],c=colc[wh];
    if(!a&&!b&&!c)return;
    cola[wh<<1]+=a,colb[wh<<1]+=b,colc[wh<<1]+=c;
    cola[wh<<1]%=mod,colb[wh<<1]%=mod,colc[wh<<1]%=mod;
    d[wh<<1]+=S(le,mid,a,b,c);
    d[wh<<1]%=mod;
    cola[wh<<1|1]+=a,colb[wh<<1|1]+=b,colc[wh<<1|1]+=c;
    cola[wh<<1|1]%=mod,colb[wh<<1|1]%=mod,colc[wh<<1|1]%=mod;
    d[wh<<1|1]+=S(mid+1,ri,a,b,c);
    d[wh<<1|1]%=mod;
    cola[wh]=colb[wh]=colc[wh]=0;
}
inline void update(int le,int ri,int wh,int x,int y,int a,int b,int c){
    if(le>=x&&ri<=y){
      cola[wh]+=a,colb[wh]+=b,colc[wh]+=c;
      cola[wh]%=mod,colb[wh]%=mod,colc[wh]%=mod;
      d[wh]+=S(le,ri,a,b,c);
      d[wh]%=mod;
      return;
    }
    int mid=(le+ri)>>1;
    pd(wh,le,mid,ri);
    if(mid>=x)update(le,mid,wh<<1,x,y,a,b,c);
    if(mid<y)update(mid+1,ri,wh<<1|1,x,y,a,b,c);
    d[wh]=(d[wh<<1]+d[wh<<1|1])%mod;
}
inline int q(int le,int ri,int wh,int x,int y){
    if(le>=x&&ri<=y)return d[wh];
    int mid=(le+ri)>>1,ans=0;
    pd(wh,le,mid,ri);
    if(mid>=x)ans=(ans+q(le,mid,wh<<1,x,y))%mod;
    if(mid<y)ans=(ans+q(mid+1,ri,wh<<1|1,x,y))%mod;
    d[wh]=(d[wh<<1]+d[wh<<1|1])%mod;
    return ans;
}
signed main(){
    int i,j,k;
    scanf("%lld%lld",&n,&m);
    for(i=1;i<=n;i++)scanf("%lld",&p[i]),p[i]=(p[i]+p[i-1])%mod;
    for(i=1;i<=n;i++)pp[i]=(pp[i-1]+p[i])%mod;
    for(i=1;i<=n;i++)f1[i]=(f1[i-1]+i)%mod,f2[i]=(f2[i-1]+i*i)%mod;
    build(0,n,1);
    for(i=1;i<=m;i++){
      scanf("%lld",&k);
      int le,ri,len,D;
      if(k==1){
          scanf("%lld%lld%lld",&le,&ri,&D);
          if(le>ri)swap(le,ri);
          len=ri-le+1;
          int a=D,b=(3-2*le%mod+mod)%mod*D%mod;
        int c=(le*le%mod-3*le%mod+2+mod)%mod*D%mod;
          update(0,n,1,le,ri,a,b,c);
          if(ri==n)continue;
          a=0,b=2*len*D%mod,c=(len*(len+1-2*ri)%mod+mod)%mod*D%mod;
        update(0,n,1,ri+1,n,a,b,c);
      }else {
          scanf("%lld%lld",&le,&ri);
          len=ri-le+1;
          Ans=len*q(0,n,1,n,n)%mod;
          Ans=(Ans-q(0,n,1,le-1,ri-1)+mod)%mod;
        Ans=(Ans-q(0,n,1,n-ri,n-le)+mod)%mod;
          printf("%lld\n",Ans*t%mod);
      }
    }
    return 0;
}
posted @ 2019-02-15 10:44  水题收割者  阅读(215)  评论(0编辑  收藏  举报