zoukankan      html  css  js  c++  java
  • [loj2304]泳池

    将等于$k$差分,即小于等于$k$减去小于等于$k-1$,由于两者类似,不妨仅考虑前者

    令$f_{i,j}$表示仅考虑$i$列(即$n=i$时),若前$j$行都没有障碍,此时最大面积小于等于$k$的概率

    考虑转移,对第$j+1$行是否有障碍分类讨论,并在有障碍时枚举最左边的障碍,即
    $$
    f_{i,j}=egin{cases}q^{i}f_{i,j+1}+sum_{t=1}^{i}(1-q)q^{t-1}f_{t-1,j+1}f_{i-t,j}&(ijle k)\0&(ij>k)end{cases}
    $$
    初始状态为$f_{0,j}=1$,接下来根据此式子,求出$i,jge 1$且$ijle k$或$j=0$且$ile k$的$f_{i,j}$,由于这样的状态数是$o(klog k)$的,总复杂度即为$o(k^{2}log k)$

    接下来,考虑$i>k$且$j=0$时的式子,去掉其中为0的项,即
    $$
    f_{i,0}=sum_{t=1}^{k+1}(1-q)q)^{t-1}f_{t-1,1}f_{i-t,0}f_{i,0}=sum_{t=1}^{k+1}(1-q)q^{t-1}f_{t-1,1}f_{i-t,0}
    $$
    记$g_{t}=(1-q)q^{t-1}f_{t-1,1}$,即为常数,预处理后即递推式$f_{i,0}=sum_{t=1}^{k+1}g_{t}f_{i-t,0}$

    对于一个多项式$F$,令$G(F)=sum_{i=0}^{infty}f_{i,0}[x^{i}]F$(后者即指$F$的$i$次项系数),问题即求$G(x^{n})$

    注意到对于函数$G$,有以下两个性质:

    1.$G((x^{k+1}-sum_{i=1}^{k+1}g_{i}x^{k-i+1})x^{t})=f_{t+k+1,0}-sum_{i=0}^{k}g_{i}f_{t+k+1-i,0}=0$

    (即$i=k+t+1$时的递推式,因此显然相等)

    2.$G(F_{1})+G(F_{2})=G(F_{1}+F_{2})$,代入即成立

    综上,构造$A(x)=x^{k+1}-sum_{i=1}^{k+1}g_{i}x^{k-i+1}$,设$x^{n}=A(x)B(x)+R(x)$,即有
    $$
    G(x^n)=G(AB)+G(R)=sum_{i=0}^{infty}[x^{i}]Bcdot G(Ax^{i})+G(R)=G(R)
    $$
    换言之,问题即求$R(x)equiv x^{n}(mod A(x))$,再求$G(R)$即可

    若$R_{0}(x)equiv x^{m}(mod A(X))$,即有$R_{0}^{2}(x)equiv x^{2m}(mod A(x))$和$xR_{0}(x)equiv x^{m+1}(mod A(x))$,由此进行迭代即可,复杂度为$o(k^{2}log k)$(即暴力计算$R_{0}^{2}(x)$)或$o(klog^{2}k)$(使用ntt计算$R_{0}^{2}(x)$)

    综上,总复杂度即$o(k^{2}log k)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 1005
     4 #define mod 998244353
     5 int n,k,x,y,p,mi[N],A[N],R[N],RR[N<<1],g[N],f[N][N];
     6 int pow(int n,int m){
     7     int s=n,ans=1;
     8     while (m){
     9         if (m&1)ans=1LL*ans*s%mod;
    10         s=1LL*s*s%mod;
    11         m>>=1;
    12     }
    13     return ans;
    14 }
    15 void solve(int n,int k){
    16     if (!n){
    17         memset(R,0,sizeof(R));
    18         R[0]=1;
    19         return;
    20     }
    21     solve((n>>1),k);
    22     memset(RR,0,sizeof(RR));
    23     for(int i=0;i<=k;i++)
    24         for(int j=0;j<=k;j++)RR[i+j]=(RR[i+j]+1LL*R[i]*R[j])%mod;
    25     for(int i=2*k;i>k;i--){
    26         for(int j=1;j<=k+1;j++)RR[i-j]=(RR[i-j]-1LL*A[k+1-j]*RR[i]%mod+mod)%mod;
    27         RR[i]=0;
    28     }
    29     memcpy(R,RR,sizeof(R));
    30     if (n&1){
    31         for(int i=k;i>=0;i--)R[i+1]=R[i];
    32         R[0]=0;
    33         for(int i=1;i<=k+1;i++)R[k+1-i]=(R[k+1-i]-1LL*A[k+1-i]%mod*R[k+1]%mod+mod)%mod;
    34         R[k+1]=0;
    35     }
    36 }
    37 int calc(int k){
    38     memset(f,0,sizeof(f));
    39     for(int i=0;i<=k+1;i++)f[0][i]=1;
    40     for(int i=1;i<=k;i++)
    41         for(int j=k/i;j>=0;j--){
    42             f[i][j]=1LL*mi[i]*f[i][j+1]%mod;
    43             for(int t=1;t<=i;t++)f[i][j]=(f[i][j]+1LL*(mod+1-p)*mi[t-1]%mod*f[t-1][j+1]%mod*f[i-t][j])%mod;
    44         }
    45     for(int i=1;i<=k+1;i++)g[i]=1LL*(mod+1-p)*mi[i-1]%mod*f[i-1][1]%mod;
    46     A[k+1]=1;
    47     for(int i=1;i<=k+1;i++)A[k-i+1]=mod-g[i];
    48     solve(n,k);
    49     int ans=0;
    50     for(int i=0;i<=k;i++)ans=(ans+1LL*f[i][0]*R[i])%mod;
    51     return ans;
    52 }
    53 int main(){
    54     scanf("%d%d%d%d",&n,&k,&x,&y);
    55     p=1LL*x*pow(y,mod-2)%mod;
    56     mi[0]=1;
    57     for(int i=1;i<=k;i++)mi[i]=1LL*mi[i-1]*p%mod;
    58     printf("%d",(calc(k)-calc(k-1)+mod)%mod);
    59 } 
    View Code
  • 相关阅读:
    小技巧
    常用的交互设计软件
    Android studio 使用SVN需要忽略的文件
    android studio 使用SVN 锁定文件,防止别人修改(基于Android studio 1.4 )
    git 和 github 关系?
    Double 数据保留两位小数一:五舍六入
    设计模式
    Java中关于日期类那些方法
    ios 开源免费接口
    华为招聘机试整理5:简单四则运算
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14734661.html
Copyright © 2011-2022 走看看