题解:P17875 [FJCPC 2026] 蛇小弟与奶龙
::::info[这里是原题中的奶龙] ::::
看到奶龙就点进来了,抢到了首 A,你们都不喜欢奶龙吗?
先把概率转成计数,最后除以
考虑这个 打表可得:
证明类似数位 DP,对
那么我们要在每个
考虑枚举选过的
那么就可以 DP 了。设
边界是:
贡献即为
别忘了补上所有
时间复杂度
::::success[代码]{open}
#include<bits/stdc++.h>
#define mod 1000000007
#define int long long
#define N 200005
using namespace std;
int t,n,c,p,i,j,a[N],dp[N][3];
int ksm(int a,int b){
int r=1;
while(b){
if(b&1)r=r*a%mod;
a=a*a%mod;
b>>=1;
}
return r;
}
signed main(){
cin.tie(0)->sync_with_stdio(0);
cin>>t;
while(t--){
cin>>n;
for(c=i=1;i<=n;i++)cin>>a[i];
for(i=0;i<30;i++){
p=ksm(2,i)%mod;
for(j=dp[0][0]=1;j<=n;j++){
dp[j][0]=dp[j-1][0]*((a[j]&(1<<i)-1)+1)%mod;
dp[j][1]=dp[j-1][1]*((a[j]&(1<<i)-1)+1)%mod;
dp[j][2]=dp[j-1][2]*((a[j]&(1<<i)-1)+1)%mod;
if(a[j]>>i&1){
(dp[j][2]+=dp[j-1][1]*p)%=mod;
(dp[j][1]+=dp[j-1][0]+dp[j-1][2]*p)%=mod;
}
}
(c+=dp[n][2])%=mod;
}
for(i=1;i<=n;i++)c=c*ksm(a[i]+1,mod-2)%mod;
cout<<c<<'\n';
}
}
::::