【XR-4】混乱度

题目链接

【XR-4】混乱度

题目描述

有n种颜色的球,第i种颜色有 a i a_{i} ai个,我们定义 f ( l , r ) = ( ∑ i = l r a i ) ! ∏ j = l r a j ! % p f(l,r)=\frac{(\sum_{i=l}^{r}a_{i})!}{\prod_{j=l}^{r}a_{j}!}\%p f(l,r)=j=lraj!(i=lrai)!%p,这里我们定义 0 ! = 1 0!=1 0!=1,求 ∑ l = 1 n ∑ r = l n f ( l , r ) \sum_{l=1}^{n}\sum_{r=l}^{n}f(l,r) l=1nr=lnf(l,r) ( p ∈ { 2 , 3 , 5 , 7 } ) (p\in \left\{2,3,5,7\right\}) (p{2,3,5,7})

题目解析

这题太神仙了
在考试的时候一直再想枚举左端点,右端点右移不会很多,但是一直没有想到去证明这件事情
首先我们有 f ( l , r ) = f ( l , r − 1 ) ∗ C ( ∑ i = l r a i , a r ) ( r > l ) f(l,r)=f(l,r-1)*C(\sum_{i=l}^{r}a_{i},a_{r})(r>l) f(l,r)=f(l,r1)C(i=lrai,ar)(r>l)
所以我们有 f ( l , r ) = ∏ i = l r C ( ∑ j = l i a j , a i ) f(l,r)=\prod_{i=l}^{r}C(\sum_{j=l}^{i}a_{j},a_{i}) f(l,r)=i=lrC(j=liaj,ai)
由于 p ∈ { 2 , 3 , 5 , 7 } p\in \left\{2,3,5,7\right\} p{2,3,5,7},我们考虑Lucas定理,Lucas是把数都表示成在p进制下的再每一位对应组合数进行计算,所以我们先把a都转成p进制,然后枚举左端点,右移右端点,发现把a所对应的p进制数相加如果发生进位,则之后的结果都为0,但是这样的话我们可以构造出 m a x { r − l } = p l o g p w max\left\{r-l\right\}=plog_{p}w max{rl}=plogpw,这样你的时间复杂度就变成了 O ( n p l o g p w l o g p w ) O(nplog_{p}wlog_{p}w) O(nplogpwlogpw)(0当然要缩掉啊),我们考虑存下每种颜色他非0的位置,这样时间复杂度就优化成 O ( n p l o g p w ) O(nplog_{p}w) O(nplogpw)

#include
#define pb(x) push_back(x)
#define ll long long
using namespace std;
const int N=5e5+10;
const int M=10;
const int D=70;
int n,p,len;
int sum[N],f[M][M],b[D+2];
vector<int>a[N],q[N];
ll ans,x;
int main(){
	scanf("%d%d",&n,&p);
	int len=0; sum[len]=1;
	for (int i=1;i<=n;i++){
		scanf("%lld",&x);
		if (x!=0) {
		len++; sum[len]=1;
		int cnt=0;
		while (x) {
		if (x%p) q[len].pb(cnt);
		a[len].pb(x%p),x/=p;
		cnt++;
		}
		} else sum[len]++;
	}
	for (int i=0;i<=len;i++) ans+=(ll)(sum[i]-1)*sum[i]/2;
	f[0][0]=1;
	for (int i=1;i<=p;i++) {
		f[i][0]=1; f[i][i]=1;
		for (int j=1;j<i;j++) f[i][j]=(f[i-1][j]+f[i-1][j-1])%p;
	}
	for (int i=1;i<=len;i++) {
		for (int j=0;j<=D;j++) b[j]=0;
		int s=1;
		bool check=1;
		for (int j=i;j<=len;j++) {
			for (int k=0;k<q[j].size();k++) {
				if (b[q[j][k]]+a[j][q[j][k]]>=p) {
					check=0; break;
				}
				b[q[j][k]]+=a[j][q[j][k]];
				s=s*f[b[q[j][k]]][a[j][q[j][k]]]%p;
			}
			if (!check) break;
			ans+=1ll*s*sum[i-1]*sum[j];
		}  
	}
	printf("%lld\n",ans);
}

你可能感兴趣的:(【XR-4】混乱度)