zoukankan      html  css  js  c++  java
  • [Luogu5320][BJOI2019]堪破神机(DP+斯特林数)

    https://www.cnblogs.com/cjyyb/p/10747543.html

    特征方程+斯特林反演化简式子,要注意在模998244353意义下5没有二次剩余,所以每个数都要用$a+bsqrt{5}$的形式表示,运算类似复数。

    斯特林反演的几个用法:

    1.下降幂转幂:连续求和时可以通过等比数列求和公式加速。

    2.幂转下降幂:类似自然数幂和地用有限微积分加速,或帮助设计DP状态。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     4 typedef long long ll;
     5 using namespace std;
     6 
     7 const int N=510,mod=998244353,i2=499122177,i5=598946612,i6=166374059;
     8 
     9 ll V,L,R;
    10 int T,m,K,S[N][N],C[N][N];
    11 
    12 struct num{ int a,b; }z;
    13 num operator +(const num &a,const num &b){ return (num){(a.a+b.a)%mod,(a.b+b.b)%mod}; }
    14 num operator -(const num &a,const num &b){ return (num){(a.a-b.a+mod)%mod,(a.b-b.b+mod)%mod}; }
    15 num operator *(const num &a,const num &b){ return (num){int((1ll*a.a*b.a+V*a.b*b.b)%mod),int((1ll*a.b*b.a+1ll*a.a*b.b)%mod)}; }
    16 num operator *(const num &a,int b){ return (num){int(1ll*a.a*b%mod),int(1ll*a.b*b%mod)}; }
    17 
    18 int ksm(int a,ll b){
    19     int res=1;
    20     for (; b; a=1ll*a*a%mod,b>>=1)
    21         if (b & 1) res=1ll*res*a%mod;
    22     return res;
    23 }
    24 
    25 num ksm(num a,ll b){
    26     num res=(num){1,0};
    27     for (; b; a=a*a,b>>=1)
    28         if (b & 1) res=res*a;
    29     return res;
    30 }
    31 
    32 num Inv(num a){ return (num){a.a,(mod-a.b)%mod}*ksm((1ll*a.a*a.a-V*a.b*a.b%mod+mod)%mod,mod-2); }
    33 
    34 int main(){
    35     freopen("calc.in","r",stdin);
    36     freopen("calc.out","w",stdout);
    37     scanf("%d%d",&T,&m);
    38     if (m==2) V=5; else V=3;
    39     while (T--){
    40         scanf("%lld%lld%d",&L,&R,&K); S[0][0]=1;
    41         rep(i,1,K) rep(j,1,i) S[i][j]=(S[i-1][j-1]-1ll*S[i-1][j]*(i-1)%mod+mod)%mod;
    42         rep(i,0,K) C[i][0]=1;
    43         rep(i,1,K) rep(j,1,i) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
    44         num a,b,A,B; ll len=R-L+1;
    45         if (m==2) L++,R++,a=(num){i2,i2},b=(num){i2,mod-i2},A=(num){0,i5},B=(num){0,mod-i5};
    46         else R>>=1,L=(L+1)>>1,a=(num){2,1},b=(num){2,mod-1},A=(num){i2,i6},B=(num){i2,mod-i6};
    47         int ans=0; ll t=R-L;
    48         rep(i,0,K){
    49             num res=z;
    50             rep(j,0,i){
    51                 num s=ksm(A,j)*ksm(B,i-j)*C[i][j];
    52                 num p=ksm(ksm(a,L),j)*ksm(ksm(b,L),(i-j));
    53                 num q=ksm(a,j)*ksm(b,i-j);
    54                 num w=p*((ksm(q,t+1)-(num){1,0})*Inv(q-(num){1,0}));
    55                 if (q.a==1 && q.b==0) w=p*((R-L+1)%mod);
    56                 res=res+s*w;
    57             }
    58             ans=(ans+1ll*res.a*S[K][i])%mod;
    59         }
    60         int Ans=1ll*ans*ksm(len%mod,mod-2)%mod;
    61         rep(i,1,K) Ans=1ll*Ans*ksm(i,mod-2)%mod;
    62         printf("%d
    ",Ans);
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    【BZOJ 4581】【Usaco2016 Open】Field Reduction
    【BZOJ 4582】【Usaco2016 Open】Diamond Collector
    【BZOJ 4580】【Usaco2016 Open】248
    【BZOJ 3754】Tree之最小方差树
    【51Nod 1501】【算法马拉松 19D】石头剪刀布威力加强版
    【51Nod 1622】【算法马拉松 19C】集合对
    【51Nod 1616】【算法马拉松 19B】最小集合
    【51Nod 1674】【算法马拉松 19A】区间的价值 V2
    【BZOJ 2541】【Vijos 1366】【CTSC 2000】冰原探险
    【BZOJ 1065】【Vijos 1826】【NOI 2008】奥运物流
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10799332.html
Copyright © 2011-2022 走看看