タイトルます。https://nanti.jisuanke.com/t/41350
分析:オーバー転置最初の文字列
状態遷移、ためのみ5つの状態、iがj個の最小コストが列挙の状態に状態[K] [I] - > [J] [k]の最小値は(0 <= K <= 4)
0:初期状態
1:2
2時20分
3:201
2019:4
MAT [i] [j]はiがjに転送される状態の最小コストを表します
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 #define LSON根<< 1、L、midd の#define rsonルート<< 1 | 1、midd + 1、R用 のconst int型 N = 2E5 + 5 。 構造体ノード{ int型のマット[ 5 ] [ 5 ]。 無効のinit(){ memsetの(マット、0x3fを、はsizeof (マット))。 } ノード演算子 +(constのノード&B){ ノードRET。 以下のために(int型私は= 0 ;私は< 5 ; I ++) のための(INT J = 0 ; J < 5 ; J ++ ){ ret.mat [I] [J] = N。 用(int型のk = 0 ; <K 5を k個++; ) ret.mat [I] [J] =分(ret.mat [I]、[J]、マット[I] [K] + b.mat [K] [ J]); } 戻りRET。 } }ツリー[N << 2 ]、ANS。 チャーS [N]。 ボイドビルド(int型のルート、int型の L、int型R){ もし(L == R){ ため(int型 i = 0 ; iが< 5 I ++; ) のための(INT J = 0 ; J < 5 ; J ++ ) 場合(!J = I) ツリー[ルート] .MAT [I]を[ J] = N。 他の 木[ルート] .MAT [I] [J] = 0 ; もし(S [L] == ' 8 ' ) ツリー[ルート] .MAT [ 4 ] [ 4 ] = 1、ツリー[ルート] .MAT [3 ] [ 3 ] = 1 。 そう であれば(S [L] == ' 9 ' ) ツリー[ルート] .MAT [ 3 ] [ 3 ] = 1、ツリー[ルート] .MAT [ 3 ] [ 4 ] = 0 ; そう であれば(S [L] == ' 1 ' ) ツリー[ルート] .MAT [ 2 ] [ 2 ] = 1、ツリー[ルート] .MAT [ 2 ] [ 3 ] = 0 ; それ以外の 場合(S [L] == "0 ' ) ツリー[ルート] .MAT [ 1 ] [ 1 ] = 1、ツリー[ルート] .MAT [ 1 ] [ 2 ] = 0 ; そう であれば(S [L] == ' 2 ' ) ツリー[ルート] .MAT [ 0 ] [ 0 ] = 1、ツリー[ルート] .MAT [ 0 ] [ 1 ] = 0 ; 返します。 } INT midd =(L + R)>> 1 。 (LSON)を構築します。 (rson)を構築します。 ツリー[ルート] =ツリー[ルート<<1 ] +ツリー[ルート<< 1 | 1 ]。 } ボイドクエリ(int型 L、INT R、int型の根、int型の L、INT R){ 場合(L <= 1 && R <= R){ ANS = ANS + ツリー[ルート]。 返します。 } INT midd =(L + R)>> 1 。 もし(L <= midd) クエリ(L、R、LSON)。 もし(R> midd) クエリ(L、R、rson)。 } チャーF [N]。 INT {main()の int型nは、T。 scanf関数(" %d個の%のD "、&N、&T)。 scanf関数(" %sの"、F + 1 )。 以下のために(int型私= 1、J、= N; iが<= N; iが++、j-- ) S [I] = F [J]。 // coutの<<てendl; ビルド(1、1 、N) 一方、(t-- ){ int型のL、R。 scanf関数(" %dの%のD "、&L&R)。 int型 L = N-R + 1、R = N-L + 1; ANS.init(); 以下のために(int型 i = 0 ; iは< 5 ; iは++ ) ANS.mat [i]は[I] = 0 ; クエリ(L、R、1、1 、N) INT年= ANS.mat [ 0 ] [ 4 ]。 もし(年齢== N) 年 = - 1 ; printf(" %d個の\ nを" 、年); } 戻り 0 。 }