[CF1151F]Sonya and Informatics
做题时间:2022.10.12
给定一个长度为 的01串,进行 次操作,每次操作等概率选择两个位置 ,交换 位置上的数。求 次操作后,该01串变成不降序列的概率,答案对 取模
第一行两个整数
第二行 个整数表示01串
一行一个整数表示概率
计数dp、矩阵快速幂
发现0和1的数量保持不变。假设串中有 个0,那么最终的序列会变成连续 个0和连续 个1拼成的串。发现前 个数中0的个数会有影响,于是设 表示第 次操作后前 个数中有 个0的方案数,考虑第 次操作将前 个数中0的个数+1/不变/-1:
- +1则是选择前 个数中的1,共 个,以及后 个数中的0,共 个,总共 种选法,设他为 ,因此方案数为
- 不变则是在前 个数或后 个数之间任意对调,或将前面的0/1与后面对应的0/1对调,共 种,设他为 ,则方案数为
- -1则是选择前 个数中的0,共 种选择,以及后 个数中的1,共 种选择,总共 种选法,设他为 ,则方案数为
也就是:
设 表示前 个数种0的个数,初始化即为
然后发现第一维很大,第二维很小,所以可以使用矩阵快速幂,即:
最后的答案就是:
#include<cstdio> #include<iomanip> #include<cstring> #define int long long using namespace std; const int N=1e2+50,mod=1e9+7,Inv2=500000004; int n,m,k,A[N],B[N],C[N],a[N],t; struct Matrix{ int num[N][N]; Matrix(){memset(num,0,sizeof num);} Matrix operator *(const Matrix &b) const{ Matrix c; for(int i=0;i<=m;i++){ for(int j=0;j<=m;j++){ for(int k=0;k<=m;k++){ c.num[i][j]=(c.num[i][j]+num[i][k]*b.num[k][j])%mod; } } } return c; } }base,T,One; void init() { for(int i=0;i<=m;i++) One.num[i][i]=1; base.num[0][t]=1; for(int j=0;j<=m;j++){//初始化A,B,C A[j]=(m-j+1)*(m-j+1)%mod; B[j]=(n-m)*(n-m-1)*Inv2%mod+m*(m-1)*Inv2%mod+(m-j)*(n-2*m+j)%mod+j*(m-j); C[j]=(j+1)*(n-2*m+j+1)%mod; B[j]=(B[j]+mod)%mod; A[j]=(A[j]+mod)%mod; C[j]=(C[j]+mod)%mod; } for(int j=0;j<=m;j++){ if(j) T.num[j-1][j]=A[j]; if(j<m) T.num[j+1][j]=C[j]; T.num[j][j]=B[j]; } } Matrix Pow(Matrix a,int b)//矩阵快速幂 { Matrix ans=One,Base=a; while(b){ if(b&1){ ans=ans*Base; } Base=Base*Base; b>>=1; } return ans; } inline int Fast_Pow(int a,int b) { int ans=1,base=a; while(b){ if(b&1) ans=ans*base%mod; base*=base,base%=mod; b>>=1; } return ans; } signed main() { scanf("%lld%lld",&n,&k); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); if(!a[i]) m++; } for(int i=1;i<=m;i++) t+=(a[i]==0); init(); base=base*Pow(T,k); Matrix t=Pow(T,k); int st=max(2*m-n,0ll); int sum=0; for(int i=st;i<=m;i++) sum+=base.num[0][i],sum%=mod; printf("%lld\n",base.num[0][m]*Fast_Pow(sum,mod-2)%mod); return 0; }
本文作者:lxzy
本文链接:https://www.cnblogs.com/Unlimited-Chan/p/16786391.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步