LGP3281题解

当你看到一个东西的时候,GF 有可能比 DP 更方便。处理贡献也有可能比 DP 更方便。

这个题意明显是让我们计算 \(S(r)-S(l-1)\) 之类的东西(

所以直接考虑前缀的答案就好了(

考虑将一个数分为两个部分,顶着最高位的前缀和没顶着最高位的后缀。

我们枚举这个前缀。后缀的个数是很容易计算的,前缀对答案的贡献也很容易计算。

后缀对答案的贡献不是那么好计算。我们直接考虑每个元素对答案的贡献。

设所有长度为 \(n\) 的数的前缀和之和为 \(g[n]\),所有长度为 \(n\) 的数的价值为 \(f[n]\)

对于 \(g\),似乎很好算,有 \(g[n]=\frac{B(B-1)}{2}\times\sum_{i=1}^{n}(\sum_{j=0}^{n-i}B^{j})\times B^{n-1}=\frac{B^{n}(B-1)}{2}\times\sum_{i=1}^{n}(\sum_{j=0}^{n-i}B^{j})\)

似乎 \(f\)\(g\) 差不了多少,是 \(f[n]=\frac{B(B-1)}{2}\times\sum_{i=1}^{n}i\times(\sum_{j=0}^{n-i}B^{j})\times B^{n-1}=\frac{B^{n}(B-1)}{2}\times\sum_{i=1}^{n}i\times(\sum_{j=0}^{n-i}B^{j})\)

但是有的数被枚举时包含了前导 \(0\)

我们直接去掉包含前导 \(0\) 的原有的数的贡献,然后加上应有的贡献就行了。

注意需要再枚举一位非 \(0\)

#include<cstdio>
typedef unsigned ui;
const ui M=1e5+5,mod=20130427,inv2=10065214;
ui B,f[M],g[M],t[M],pw[M];
ui n,m,a[M],b[M];
inline void init(const ui&n){
	t[0]=1;pw[0]=1;
	for(ui i=1;i<=n;++i){
		pw[i]=1ull*pw[i-1]*B%mod;t[i]=(t[i-1]+pw[i])%mod;
	}
	for(ui i=1;i<=n;++i){
		g[i]=(g[i-1]+t[i-1])%mod;f[i]=(f[i-1]+1ull*(i-1)*t[i-1])%mod;
	}
	for(ui S(0),i=1;i<=n;++i){
		S=(S+t[i-1])%mod;f[i]=(1ull*i*S+mod-f[i])%mod;
	}
	for(ui i=1;i<=n;++i){
		f[i]=1ull*pw[i]*(B-1)%mod*inv2%mod*f[i]%mod;g[i]=1ull*pw[i]*(B-1)%mod*inv2%mod*g[i]%mod;
	}
	for(ui i=0;i<=n;++i){
		if(!t[i])t[i]=mod;if(!pw[i])pw[i]=mod;if(!f[i])f[i]=mod;if(!g[i])g[i]=mod;
	}
}
inline ui F(ui*a,const ui&n){
	ui ans(0);
	for(ui i=1;i<=n;++i)ans=(ans+1ull*a[i]*i%mod*t[n-i])%mod;
	return ans;
}
inline ui Solve(ui*a,const ui&n){
	ui ans(0);
	for(ui F(0),G(0),i=1;i<=n;++i){
//		for(ui c=0;c<a[i];++c){
//			const ui&tg=(1ull*G*B+1ull*i*c)%mod,&tf=(F+tg)%mod;
////			ans=(ans+1ull*g[n-i]*i+1ull*tg*(t[n-i]-1)%mod*pw[n-i]+1ull*tf*pw[n-i]+f[n-i])%mod;
//		}
		const ui&m=a[i],&sg=(1ull*G*B%mod*m+1ull*m*(m-1)%mod*inv2%mod*i)%mod,&sf=(1ull*F*m+sg)%mod;
		ans=(ans+1ull*g[n-i]*i%mod*m+1ull*sg*(t[n-i]-1)%mod*pw[n-i]+1ull*sf*pw[n-i]+1ull*f[n-i]*m)%mod;
		if(i!=n){
//			for(ui c=1;c<B;++c){
//				const ui&tg=1ull*(i+1)*c%mod,&tf=tg;
//				ans=(ans+mod-(1ull*g[n-i-1]*(i+1)+1ull*tg*(t[n-i-1]-1)%mod*pw[n-i-1]+1ull*tf*pw[n-i-1]+f[n-i-1])%mod)%mod;
//				ans=(ans+g[n-i-1]+1ull*c*(t[n-i-1]-1)%mod*pw[n-i-1]+1ull*c*pw[n-i-1]+f[n-i-1])%mod;
//			}
			const ui&m=B-1,&c=1ull*B*(B-1)%mod*inv2%mod,&sg=1ull*(i+1)*c%mod,&sf=sg;
			ans=(ans+mod-(1ull*g[n-i-1]*(i+1)%mod*m+1ull*sg*(t[n-i-1]-1)%mod*pw[n-i-1]+1ull*sf*pw[n-i-1]+1ull*f[n-i-1]*m)%mod)%mod;
			ans=(ans+1ull*g[n-i-1]*m+1ull*c*(t[n-i-1]-1)%mod*pw[n-i-1]+1ull*c*pw[n-i-1]+1ull*f[n-i-1]*m)%mod;
		}
		G=(1ull*G*B+1ull*i*a[i])%mod;F=(F+G)%mod;
	}
	return ans;
}
signed main(){
	scanf("%u",&B);
	scanf("%u",&n);for(ui i=1;i<=n;++i)scanf("%u",a+i);
	scanf("%u",&m);for(ui i=1;i<=m;++i)scanf("%u",b+i);
	init(n>m?n:m);printf("%u",(Solve(b,m)+mod-Solve(a,n)+F(b,m))%mod);
}
posted @ 2022-03-16 09:06  Prean  阅读(21)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};