CF868G El Toll Caves

Link
最优的决策肯定是尽量均摊,不妨从前往后做,那么我们可以将\(n,k\)都除以\(\gcd(n,k)\)
\(f_i\)表示在第\(i\)个洞穴找到宝藏的期望天数,那么答案为\(\frac{\sum f_i}n\)
考虑\(f_i\)的转移式:

\[f_i= \begin{cases} f_{i-k}+1&i\in[k,n)\\ (1-p)f_i+1&i\in[0,k) \end{cases} \]

\(A(f_i)=f_{i+k},B(f_i)=f_{i+k-n}\),那么我们要求的就是\(ans=\sum\limits_{i=0}^{k-1}S1(f_i)+\sum\limits_{i=k}^{n-1}S2(f_i)\)
考虑将\((n,k)\)递归至\((k,k'=n\bmod k)\)的子问题,此时\(ans=\sum\limits_{i=0}^{k'-1}S1'(f_i)+\sum\limits_{i=k}^{n-1}S2'(f_i)\)
不难发现\(S_1'=S1+\sum\limits_{i=1}^{\lfloor\frac nk\rfloor}S2(A^i),S2'=S1+\sum\limits_{i=1}^{\lfloor\frac nk\rfloor-1}S2(A^i)\)
注意到\(f_{i+k-k'}=B(A^{\lfloor\frac nk\rfloor}(f_i))\),因此\(f_{i+k'-k}=A^{-\lfloor\frac nk\rfloor}(B^{-1}(f_i))\),这就是\(B'\)
同理可以推出\(A'\)\(f_{i+k'}=A^{-\lfloor\frac nk\rfloor-1}(B^{-1}(f_i))\)

#include<cstdio>
#include<numeric>
using i64=long long;
const i64 P=1000000007,i2=P-P/2;
int read(){int x;scanf("%d",&x);return x;}
i64 pow(i64 a,i64 k){i64 r=1;for(;k;k>>=1,a=a*a%P)if(k&1)r=r*a%P;return r;}
i64 f(i64 x,i64 y){return y<=0? 0:x==1? y:pow(x-1,P-2)*(pow(x,y)-1)%P;}
i64 g(i64 x,i64 y){return y<=0? 0:x==1? y*(y+1)/2%P:pow(x-1,P-2)*((pow(x,y)-1)*pow(x-1,P-2)%P*x%P-y+P)%P;}
i64 solve(i64 n,i64 k,i64 a1,i64 a0,i64 b1,i64 b0,i64 s,i64 s1,i64 s2)
{
    if(n==1) return (s1*b0%P*pow(1-b1+P,P-2)+s)%P;
    i64 q=(n-1)/k,r=n-q*k,x,y,A1,A0,B1,B0,S,S1,S2;
    x=b1*pow(a1,q-1)%P,y=(a0*b1%P*f(a1,q-1)+b0)%P,A1=pow(x,P-2),A0=P-y*A1%P;
    x=b1*pow(a1,q)%P,y=(a0*b1%P*f(a1,q)+b0)%P,B1=pow(x,P-2),B0=P-y*B1%P;
    S=(s2*a0%P*(r*f(a1,q)%P+k*g(a1,q-1)%P)+s)%P,S1=(s2*a1%P*f(a1,q)+s1)%P,S2=(s2*a1%P*f(a1,q-1)+s1)%P;
    return solve(k,r,A1,A0,B1,B0,S,S1,S2);
}
void solve()
{
    i64 n,k,d;
    n=read(),k=read(),d=std::gcd(n,k),n/=d,k/=d;
    printf("%lld\n",solve(n,k,1,1,i2,1,0,1,1)*pow(n,P-2)%P);
}
int main(){for(int t=read();t;--t) solve();}
posted @ 2020-05-22 19:27  Shiina_Mashiro  阅读(294)  评论(0编辑  收藏  举报