質問の意味:1:あなたの文字列を与えるために、2がある場所の文字を変更します。2:配列2017、及び2016ない配列を含むサブストリングを作成、削除する文字の最小数のサブストリングrに問い合わせLは、?
思考:ツリーセグメントDPを、我々は、1を0の状態を設定し、2、3、4は、次のとおりと組み合わさヌル、2、20、最小コスト201、2017年、我々は、状態遷移行列を取るために断面寸法セグメントツリーを使用し、二つの隣接するサブストリングに直接転送。
コード:
#include <ビット/ STDC ++ H> に#define INF 0x3f3f3f3f の#define LS(<< 1 O) の#define RS(O << 1 | 1) 使用して名前空間std。 const int型MAXN = 200010; [MAXN] int型。 チャーS [MAXN]。 構造体ノード{ int型のF [5] [5]。 INITを無効(INT X){ (INT i = 0; iは<5; I ++)のために{ ため(int型J = 0; J <5; J ++){ (I == j)が続けば、 F [i] [j]はINFを=。 } } もし(x == 2){ F [0] [0] = 1、F [0] [1] = 0; }そうであれば(x == 0){ F [1] [1] = 1、F [1] [2] = 0; }そうであれば(x == 1){ F [2] [2] = 1、F [2] [3] = 0; }もしそうでなければ(X == 7){ F [3] [3] = 1、F [3] [4] = 0; }もしそうでなければ(X == 6){ F [3] [3] = 1。 F [4] [4] = 1。 他の場合}(X == -1){ ため(; iは5 <; I = 0 int型私は++) F [i]は[I] = INF。 }他{ ため(; iは5 <; I = 0 int型私は++) F [i]は[I] = 0; } } ボイドプリント(){ (I = 0 int型、iが5 <; I ++の)のために{ ため(INT J = 0; J <5; J ++){ IF(F [I] [J] == INF)のprintf( "INF"); 他のprintf( "%dの"、F [i]は[J])。 } のprintf( "の\ n"); } } }。 ノードTR [MAXN * 4]。 ノードマージ(ノードT1、ノードT2){ ノードANS。 ans.init(-1)。 // ans.init(-1); // printfの( "ANSの\ nを"); // ans.print(); } // printfの( "T1の\ nを"); // t1.print(); // printfの( "T2の\ nを"); // t2.print(); 以下のために(; iは5 <; I = 0 int型私は++){ ため(int型J = I; J <5; J ++){ ための(int型K = I; K <= J; ++ K){ ans.f [I] [ J] =分(ans.f [I]、[J]、t1.f [I] [K] + t2.f [K] [J])。 } } } //のprintf( "ANSする\ n"); // ans.print(); ANSを返します。 } ボイドビルド(int型、L、O INT、INT R){ (L == R)なら、{ TR [O] .INIT([L])。 返します。 } INT半ば=(L + R)>> 1。 (LS、L、ミッド)を構築。 (RS、ミッド+ 1、r)を構築します。 TR [O] =マージ(TR [LS]、TR [RS])。 {(L == R)場合 ボイド更新(int型、L、O INT、INT R、INT QL、QR INT、INTヴァル){ それ以外(QR>中旬)ANS =クエリ(RS、ミッド+ 1、Rであれば、 TR [O] .INIT(ヴァル)。 返します。 } INT半ば=(L + R)>> 1。 IF(QL <= MID)更新(LS、L、中間、QL、QR、ヴァル)。 (QR> MID)更新(RS、ミッド+ 1、R、QL、QR、val)であれば、 TR [O] =マージ(TR [LS]、TR [RS])。 } ノードクエリー(INT 0、int型のL、R INT、INT QL、QR INT){ IF(L> = QL && R <= QR){ 戻りTR [O]。 } INT半ば=(L + R)>> 1。 ノードANS; ans.init(-1)。 IF(QL <=ミッド&& QR> MID)ANS =(クエリ(LS、L、中間、QL、QR)、クエリ(RS、ミッド+ 1、R、QL、QR))マージ。 他のANS =クエリ(LS、L、ミッド、QL、QR)(QL <= MID)の場合。 ANSを返します。 } int型のmain(){ int型N、M、L、R。 scanf関数( "%d個の%d個"、 scanf関数( "%sの"、S + 1)。 以下のために(INT i = 1; iが<= N; iは++){ [I] = sの[I] - '0'。 } (1、1、n)を構築します。 {(; I <= M I ++はiは1 = INT)のため のscanf( "%dの%のD"、&L&R)。 ノードANS =クエリ(1、1、N、L、R)。 IF(ans.f [0] [4] == INF)のprintf( " - 1つの\ n"); 他のprintf( "%Dを\ n"、ans.f [0] [4])。 } }