有一个长度为 nnn 的整数序列,每个元素在 [1,m][1,m][1,m] 中独立均匀随机,求序列的最长连续等子段长度期望长度乘 mnm^nmn,对输入的质数 ppp 取模。
例如,{1,2,2,2,3,3,3,3,2,2,1}\{1,2,2,2,3,3,3,3,2,2,1\}{1,2,2,2,3,3,3,3,2,2,1} 的最长连续等子段长度为 444。
1≤n≤3∗105,1≤m≤108,0.99∗109≤p≤1.01∗109,and p is a prime1\leq n\leq 3*10^5,1\leq m\leq 10^8,0.99*10^9\leq p\leq 1.01*10^9,and \ p\ is\ a\ prime1≤n≤3∗105,1≤m≤108,0.99∗109≤p≤1.01∗109,and p is a prime
思路和题解基本一样。
考虑计算 max≤k\max \leq kmax≤k 的方案数。
设 f[i]f[i]f[i] 表示前 iii 个的方案数,显然有转移 f[0]=mm−1,f[i]=∑j=max(0,i−k)i−1f[j]f[0]=\frac{m}{m-1},f[i]=\sum_{j=max(0,i-k)}^{i-1} f[j]f[0]=m−1m,f[i]=∑j=max(0,i−k)i−1f[j]
前缀和优化即可得到 S[0]=mm−1,S[i]=mS[i−1]+(1−m)S[i−k−1]S[0]=\frac{m}{m-1},S[i]=mS[i-1]+(1-m)S[i-k-1]S[0]=m−1m,S[i]=mS[i−1]+(1−m)S[i−k−1]
考虑组合意义,枚举跳 k+1k+1k+1 步的次数即可在 O(nlnn)O(n\ln n)O(nlnn) 时间内得到答案,至于 f[0]f[0]f[0] 为什么这么奇怪,因为第一步转移应该乘的是 mmm 而不是 m−1m-1m−1。
#include<bits/stdc++.h>
using namespace std;
const int N=300010;
int n,m,mod,fac[N],inv[N];
int ksm(int x,int t){
int tot=1;
while(t){
if(t&1) tot=1ll*tot*x%mod;
x=1ll*x*x%mod;
t/=2;
}
return tot;
}
int C(int x,int y){
return 1ll*fac[x]*inv[y]%mod*inv[x-y]%mod;
}
int main(){
scanf("%d %d %d",&n,&m,&mod);
fac[0]=1;for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
inv[n]=ksm(fac[n],mod-2);for(int i=n-1;i>=0;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
int ans=ksm(m,n),t=ksm(m,n);
for(int k=1;k<=n;k++){
int tot=0;
for(int a=0;a*(k+1)<=n;a++)
tot=(tot+1ll*ksm(1+mod-m,a)*ksm(m,n-a*(k+1))%mod*C(n-a*k,a))%mod;
for(int a=0;a*(k+1)<n;a++)
tot=(tot+mod-1ll*ksm(1+mod-m,a)*ksm(m,n-1-a*(k+1))%mod*C(n-1-a*k,a)%mod)%mod;
tot=1ll*tot*ksm(m-1,mod-2)%mod*m%mod;
ans=(1ll*ans+t+mod-tot)%mod;
}
printf("%d",ans);
}
该博客探讨了如何计算长度为n的整数序列在[1,m]范围内随机分布时,最长连续等子段长度的期望值,并给出了一种O(nlnn)时间复杂度的解决方案。通过前缀和优化和组合数学的方法,计算不同长度子段的方案数,最终求得期望值并模p得到答案。
1152

被折叠的 条评论
为什么被折叠?



