CodeForces - 1051E:Vasyaとビッグ整数(Z算法&DP)

問題の意味:指定された文字列S、A、B。今あなたを聞かせてSは[A、B]の範囲内の各切断部は、プログラム番号を尋ねるように切り出します。

考える:そこ式、DP [I] =ΣDP [J](S [J + 1、i]は、 法的な範囲内で)。N | | M及びNは最長の共通のプレフィックス長LCP、文字列M> = N文字列の条件が= LCPであるとし、又は(LCP <| N | && M [LCP + 1]> N [LCA + 1 ]);共感未満。DPは、プレフィックスとO(N)で測定範囲を見つけることができます。

LCPは明らかに要件をexkmpすることができます。Z最近発見されたアルゴリズムが良く書かれています。ビットを試してみてください。ここでリンクアップしようとしている2回は、より快適になります。

#include <ビット/ STDC ++ H>
 の#define担当者(iは、、B)のための式(I ++ iは= int型;私は= Bを<)
 使用して 名前空間STDを、
const  int型 MAXN = 1000010 ;
const  int型のMod = 998244353 ;
チャー S [MAXN << 1 ]、L [MAXN]、R [MAXN]。
INT [MAXN】Z1、Z2 [MAXN]、レナ、lenl、lenr。
ボイド Zは、(char型 []、char型 T []、INT Z [])
{ 
    int型、F =のSTRLEN(A + 1)=のSTRLEN W(T + 1 )。
    [F + 1 ] = ' '; 担当者(I、1、W)[F + 1 + I] = tの[I]。INT、N = F + W + 1 
    Z [ 1 ] = N。INTは L = 0、R = 0 
    担当者(I、2 、N){
         場合(R <I)Z [I] = 0 ;
        他の Z [i]は=分(R-I + 1、Z [I-L + 1 ])。
        一方(I + Z [i]が<= N [I + Z [i]は] && == [Z [i]が+ 1 ])Z [I] ++ ;
        もし(I + Z [1] - 1 > R)L = I、R = I + Z [1] - 1 
    } 
    担当者(I、1、W)Z [i]は= Z [F + 1 + I]; 
} 
INT DP [MAXN]和[MAXN]。
INT メイン()
{ 
    scanf関数(" %S%S%S "、S + 1、L + 1、R + 1 )。
    レナ = strlenを(S + 1)。lenl = STRLEN(L + 1)。lenrの=のSTRLEN(R + 1 )。
    Z(L、S、Z1); Z(R、S、Z2)。
    DP [レナ + 1 ] =和[レナ+ 1 ] = 1 以下のためにint型 =レナをIを、I> = 1 ; i-- ){ 
        和[I]=和[I + 1 ]。
        もし(S [I] == ' 0 ')DP [I] =(L [ 1 ] == ' 0 ')* DP [I + 1 ]、和[I] =(SUM [I] + DP [I] )%のMod。
        {
             int型 L = Iは、(i + lenr- lenl、R =分+ 2 、レナ)。
            もし(Z1 [I] == lenl || S [I + Z1 [I]]> L [Z1 [I] + 1 ])L-- もし(R <レナ&&(Z2 [I] == lenr || S [I + Z2 [I] <R [Z2 [I] + 1 ]))R ++ もし(L <= R)DP [I] =(和[L + 1 ] -sum [R + 2] + MOD)%MOD、和[I] =(SUM [I] + DP [I])%のMod。
        } 
    } 
    のprintf(" %d個の\ n "、DP [ 1 ])。
    リターン 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/hua-dong/p/11440329.html