zoukankan      html  css  js  c++  java
  • [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}^{r-1}ci-sum_{i=n-r}^{n-l}ci$,用线段树维护ci数组
    考虑对于[l,r,v]的修改操作(记$L=r-l+1$,注意不保证$lle r$),影响分为两部分:
    1.$r<i$的部分,化简得到为$ci+=Lvcdot i-L(l+r-2)v/2$
    2.$lle ile r$的部分,化简得到$ci+=v/2cdot i^{2}-v(2l-3)/2cdot i+(L+1)(L+2)v/2$
    对于1,i和$i^{2}$分别建立一颗线段树即可维护,注意实现常数(比如懒标记为0就不用下传)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 200005
     4 #define mod 1000000007
     5 #define ny 500000004
     6 #define L (k<<1)
     7 #define R (L+1)
     8 #define mid (l+r>>1)
     9 int n,m,p,x,y,z,v[3][N<<2],laz[3][N<<2],f[3][N<<2];
    10 void build(int k,int l,int r){
    11     if (l==r){
    12         v[0][k]=1;
    13         v[1][k]=l;
    14         v[2][k]=1LL*l*l%mod;
    15         return;
    16     }
    17     build(L,l,mid);
    18     build(R,mid+1,r);
    19     for(int i=0;i<3;i++)v[i][k]=(v[i][L]+v[i][R])%mod;
    20 }
    21 void upd(int p,int k,int x){
    22     laz[p][k]=(laz[p][k]+x)%mod;
    23     f[p][k]=(f[p][k]+1LL*x*v[p][k])%mod;
    24 }
    25 void down(int k){
    26     for(int i=0;i<3;i++){
    27         if (!laz[i][k])continue;
    28         upd(i,L,laz[i][k]);
    29         upd(i,R,laz[i][k]);
    30         laz[i][k]=0;
    31     }
    32 }
    33 void update(int p,int k,int l,int r,int x,int y,int z){
    34     if ((l>y)||(x>r))return;
    35     if ((x<=l)&&(r<=y)){
    36         upd(p,k,z);
    37         return;
    38     }
    39     update(p,L,l,mid,x,y,z);
    40     update(p,R,mid+1,r,x,y,z);
    41     for(int i=0;i<3;i++)f[i][k]=(f[i][L]+f[i][R]+1LL*v[i][k]*laz[i][k])%mod;
    42 }
    43 void update(int x,int y,int z){
    44     int l=y-x+1,zz=1LL*z*ny%mod;
    45     update(0,1,1,n,y+1,n,mod-1LL*l*(x+y-2)%mod*zz%mod);
    46     update(1,1,1,n,y+1,n,1LL*l*z%mod);
    47     update(0,1,1,n,x,y,(x-1LL)*(x-2)%mod*zz%mod);
    48     update(1,1,1,n,x,y,(mod-2*x+3LL)*zz%mod);
    49     update(2,1,1,n,x,y,zz);
    50 }
    51 int query(int k,int l,int r,int x,int y){
    52     if ((l>y)||(x>r))return 0;
    53     if ((x<=l)&&(r<=y))return (0LL+f[0][k]+f[1][k]+f[2][k])%mod;
    54     down(k);
    55     return (query(L,l,mid,x,y)+query(R,mid+1,r,x,y))%mod;
    56 }
    57 int main(){
    58     scanf("%d%d",&n,&m);
    59     build(1,1,n);
    60     for(int i=1;i<=n;i++){
    61         scanf("%d",&x);
    62         update(i,i,x);
    63     }
    64     for(int i=1;i<=m;i++){
    65         scanf("%d%d%d",&p,&x,&y);
    66         if (x>y)swap(x,y);
    67         if (p==1){
    68             scanf("%d",&z); 
    69             update(x,y,z);
    70         }
    71         if (p==2){
    72             x=max(x,1);
    73             int s1=query(1,1,n,n,n)*(y-x+1LL)%mod;
    74             int s2=(query(1,1,n,max(x-1,1),y-1)+query(1,1,n,max(n-y,1),n-x))%mod;
    75             printf("%d
    ",(s1-s2+mod)%mod);
    76         }
    77     }
    78 }
    View Code
  • 相关阅读:
    Java的Object类
    java中String、StringBuffer、StringBuilder的区别
    Java正则表达式
    《java编程思想》P160-P180(第八章部分+第九章部分)
    《java编程思想》P140-P160(第七章复部+第八章部分)
    《java编程思想》P125-P140(第七章复用类部分)
    Servlet 工作原理解析
    大型高性能网站的十项规则
    Java 理论与实践: 并发在一定程度上使一切变得简单
    Java并发基础构建模块简介
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/12050607.html
Copyright © 2011-2022 走看看