LG5178 求和

Posted autoint

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LG5178 求和相关的知识,希望对你有一定的参考价值。

求和

给定数列 (a_1...a_n)(x_0)

满足

[ f_{i.j}=egin{cases} a_i & j=0,ileq nx_0 & j=0,i=n+1f_{i,j-1}+f_{i-1,j-1} & 0 < i,j leq n+1,j < i & ileq j end{cases} ]

[ sum_{i=0}^{n+1}sum_{j=0}^{n+1}f_{i,j} ]

但这样太水了

于是给出 (m) 个操作,每次将 (a_ldots a_r~(0le l,r le n))(p),对于每个操作,输出答案。

特别地,若 (0)(ldots r) 范围内,我们认为 (x_0) 也加 (p)

另外,在读入 (m) 个操作前,你也应该输出答案。

由于答案可能过大,输出答案对 (1234567891) 取模的结果。

(n,m leq 10^5)

题解

https://www.luogu.com.cn/blog/user7035/solution-p5178

大概可以画出这样的图:

行列0123...n-1n
1a1000...00
2a2f2,100...00
3a3f3,1f3,20...00
........................
nanfn,1fn,2fn,3...fn,n-10
n+1anfn+1,1fn+1,2fn+1,3...fn+1,n-1fn+1,n

每个点都对右方和右下方的元素有贡献。那么

[ f_{i,j}=egin{cases} 0 & ileq j\sum_{k=0}^jinom{j}{k}a_{i-k} & i>j end{cases} ]

开始大力推式子。

[ ans=sum_{i=1}^{n+1}sum_{j=0}^{i-1}f_{i,j}=sum_{i=1}^{n+1}sum_{j=0}^{i-1}sum_{k=0}^jinom{j}{k}a_{i-k} ]

在这道题里面我们显然是要对组合数进行操作来减少求和符号的数量。

反复利用

[ sum_{i=m}^ninom{i}{m}=inom{n+1}{m+1} ]

[ ans=sum_{i=1}^{n+1}sum_{k=0}^{i-1}a_{i-k}sum_{j=k}^{i-1}inom{j}{k}=sum_{i=1}^{n+1}sum_{k=1}^ia_ksum_{j=i-k}^{i-1}inom{j}{k}=sum_{i=1}^{n+1}sum_{k=1}^ia_ksum_{j=1}^kinom{i-j}{i-k}=sum_{k=1}^{n+1}a_ksum_{i=k}^{n+1}sum_{j=1}^kinom{i-j}{i-k}=sum_{k=1}^{n+1}a_ksum_{j=1}^ksum_{i=0}^{n+1-k}inom{i+k-j}{i}=sum_{k=1}^{n+1}a_ksum_{j=1}^ksum_{i=0}^{n+1-k}inom{i+k-j}{k-j}=sum_{k=1}^{n+1}a_ksum_{j=1}^kinom{n-j+2}{k-j+1}=sum_{k=1}^{n+1}a_ksum_{j=1}^kinom{n-j+2}{n-k+1}=sum_{k=1}^{n+1}a_ksum_{j=n-k+2}^{n+1}inom{j}{n-k+1}=sum_{k=1}^{n+1}a_kleft(inom{n+2}{n-k+2}-1 ight) ]

维护系数的前缀和即可。时间复杂度 (O(n+m))

CO int N=6e5+10;
int fac[N],ifac[N];
int a[N],pool[N],*s=pool+1;

IN int binom(int n,int m){
    return mul(fac[n],mul(ifac[m],ifac[n-m]));
}
int main(){
    int n=read<int>(),m=read<int>();
    fac[0]=1;
    for(int i=1;i<=n+2;++i) fac[i]=mul(fac[i-1],i);
    ifac[n+2]=fpow(fac[n+2],mod-2);
    for(int i=n+1;i>=0;--i) ifac[i]=mul(ifac[i+1],i+1);
    for(int i=1;i<=n+1;++i)if(read(a[i])<0) a[i]+=mod;
    int ans=0;
    s[0]=binom(n+2,1)-1;
    ans=mul(a[n+1],s[0]);
    for(int i=1;i<=n;++i){
        s[i]=add(s[i-1],binom(n+2,n-i+2)-1);
        ans=add(ans,mul(a[i],binom(n+2,n-i+2)-1));
    }
    printf("%d
",ans);
    while(m--){
        int l=read<int>(),r=read<int>(),p=read<int>();
        if(p<0) p+=mod;
        ans=add(ans,mul(add(s[r],mod-s[l-1]),p));
        printf("%d
",ans);
    }
    return 0;
}

以上是关于LG5178 求和的主要内容,如果未能解决你的问题,请参考以下文章

以下代码片段的算法复杂度

hdu5178 尺取

HDU 5178 pairs二分||尺取

[bzoj5178] [Jsoi2011] 棒棒糖

bzoj5178[Jsoi2011]棒棒糖 主席树

Java8 Stream针对List先分组再求和最大值最小值平均值等