求和,LGOJ5178,数论

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Deep_Kevin/article/details/102675593

正题

      Portal

      发现x其实就是a_{n+1},这题对选手对组合数性质有一定的了解。

      考虑一个a_i在那个地方会被算到,枚举向下走了多少步,再枚举一共走了多少步:

      ans=\sum_{i=1}^{n+1}a_i\sum_{k=0}^{n+1-i}\sum_{j=k}^{i+k-1} C_j^k

      发现后面那个东西的指数是相同的,那么就有

      ans=\sum_{i=1}^{n+1}a_i\sum_{k=0}^{n+1-i}C_{i+k}^{k+1}

      至于为什么可以画一个杨辉三角出来观察一下,C_k^k=C_{k+1}^{k+1},所以不断相加可以得到C_{n+1}^{k+1}

      然后这个发现上下都有一个k,就考虑C_a^b=C_a^{a-b}

      ans=\sum_{i=1}^{n+1}a_i\sum_{k=0}^{n+1-i}C_{i+k}^{i-1}    

      又发现指数相等了,那么就有:

      ans=\sum_{i=1}^{n+1}a_iC_{n+2}^{i}-1

      那么每一个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);
	}
}

猜你喜欢

转载自blog.csdn.net/Deep_Kevin/article/details/102675593