版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
正题
发现x其实就是,这题对选手对组合数性质有一定的了解。
考虑一个a_i在那个地方会被算到,枚举向下走了多少步,再枚举一共走了多少步:
发现后面那个东西的指数是相同的,那么就有
至于为什么可以画一个杨辉三角出来观察一下,,所以不断相加可以得到
然后这个发现上下都有一个k,就考虑
又发现指数相等了,那么就有:
那么每一个ai的系数都出来了,就很容易做了。
#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
long long fac[N],inv[N];
long long a[N],f[N];
long long ans=0;
const long long mod=1234567891;
int n,m;
long long C(int x,int y){
return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
long long ksm(long long x,long long t){
long long tot=1;
while(t){
if(t&1) (tot*=x)%=mod;
(x*=x)%=mod;
t/=2;
}
return tot;
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n+1;i++) scanf("%lld",&a[i]),a[i]=a[i]%mod+mod,a[i]>=mod?a[i]-=mod:0;
fac[0]=1;for(int i=1;i<=n+2;i++) fac[i]=fac[i-1]*i%mod;
inv[n+2]=ksm(fac[n+2],mod-2);for(int i=n+1;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mod;
f[0]=n+2;
for(int i=1;i<=n+1;i++){
f[i]=C(n+2,i)-1;
ans+=a[i]*f[i]%mod;
ans>=mod?ans-=mod:0;
}
for(int i=1;i<=n;i++) f[i]+=f[i-1],f[i]>=mod?f[i]-=mod:0;
printf("%lld\n",ans);
int l,r;
long long p;
while(m--){
long long tmp=0;
scanf("%d %d %lld",&l,&r,&p);p=p%mod+mod,p>=mod?p-=mod:0;
if(l==0) tmp+=f[n+1],l++;
tmp+=f[r]-f[l-1]+mod;
tmp%=mod;
ans+=tmp*p%mod,ans>=mod?ans-=mod:0;
printf("%lld\n",ans);
}
}