質問表面:https://www.cnblogs.com/Juve/articles/11487699.html
キャプテンを実行します:
重セグメントツリーとDP
良いYY
#include <iostreamの> する#include <cstdioを> する#include <CStringの> する#include <アルゴリズム> の#include <cmath> 使用して名前空間std。 const int型MAXN = 1E5 + 5。 整数nを、[MAXN]、B [MAXN]、ANS = 0、LSH [MAXN << 1]、CNT、TOT = 0。 構造体ノード{ int型のL、R、のLaz、MX。 } TR [MAXN << 4]。 ボイドビルド(int型K、int型のL、R INT){ TR [K] .L = L、T R [K] .R = R。 IF(L == R){ TR [K] .MX = 0。 返します。 } INT半ば=(L + R)>> 1。 ビルド(K << 1、L、MID)。 (K << 1 | 1、ミッド+ 1、r)を構築します。 } (int型K){ダウン無効 TR [K << 1] .laz + = TR [K] .lazと、 TR [K << 1 | 1] .laz + = TR [K] .laz。 TR [K << 1] .MX + = TR [K] .laz。 TR [K] .laz = 0。 } ボイド押し上げ(int型K){ TR [K] .MX = MAX(TR [K << 1] .MX、TR [K << 1 | 1] .MX)。 } INT query_max(INT K、INT OPL、INT OPR){ int型のL = T R [K] .L、R = T R [K] .R。 IF(OPL <= L && R <= OPR)戻りTR [K] .MX。 IF(TR [K] .laz)ダウン(K)。 半ば=(L + R)>> 1、INT RES = 0。 IF(OPL <= MID)RES = MAX(RES、query_max(K << 1、OPL、OPR))。 もし(OPR>中旬)RES = MAX(RES、query_max(K << 1 | 1、OPL、OPR)); 解像度を返します。 } ボイド更新(int型K、INT OPT、INTヴァル){ int型のL = T R [K] .L、R = T R [K] .R。 IF(L == R){ TR [K] .MX = MAX(TR [K] .MX、ヴァル)。 返します。 } (TR [K] .laz)ダウン(k)の場合。 INT半ば=(L + R)>> 1。 IF(OPT <= MID)更新(K << 1、選ぶ、ヴァル)。 他の更新(K << 1 | 1、選ぶ、val)で、 突き上げ(K)。 空隙変化(int型K、INT OPL、INT OPR){ int型のL = T R [K] .L、R = T R [K] .R。 IF(OPL <= L && R <= OPR){ ++ TR [K] .MX。 ++ TR [K] .laz。 返します。 } (TR [K] .laz)ダウン(k)の場合。 INT半ば=(L + R)>> 1。 IF(OPL <= MID)変化(K << 1、OPL、OPR)。 もし(OPR>半ば)の変化(K << 1 | 1、OPL、OPR)。 突き上げ(K)。 } (){主符号付き のscanf( "%d個"、&N); {ため(++ I; iは= N <I = 1 INT) ("%d個の%のD"、および[I]、&B [i])とのscanf。 LSH [++ TOT] [i]は、LSHを= [++ TOT] Bは= [I]。 } ソート(LSH + 1、LSH + TOT + 1)。 CNT =ユニーク(LSH + 1、LSH + TOT + 1)-lsh。 {(; iが<= N I ++ iは1 = INT)のために B [I] = LOWER_BOUND(LSH + 1、LSH + CNT + 1、B [I]) - LSH。 以下のために(INT I = N; I> = 1; - I){ IF([I]> B [I]){ int型、P = query_max(1,1、B [i]が-1)+1。 アップデート(1、[I]、P B) 変化(1、B [I] + 1、[I])。 }他{ INT P = query_max(1,1、[I] -1)+1。 アップデート(1、B [I] + 1、P); } } のprintf( "%d個の\ n"、TR [1] .MX)。 0を返します。 }
コインを投げます:
ファックDP
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> の#include <キュー> std名前空間を使用しました。 const int型MAXN = 3005; const int型のmod = 998244353; INT Lは、lenは、F [MAXN] [MAXN]、[MAXN]です。 チャーCH [MAXN]。 署名されたメイン(){ scanf関数( "%sの"、CH + 1)。 scanf関数( "%のD"、&L)。 LEN = strlenを(CH + 1)。 // coutの<< LEN <<てendl; 以下のために(; iは= LEN <; I = int型1 ++ I){ F [i]が[0] = 1; 用(int型J = I-1、J> = 1; - J){ IF(CH [J] == CH [I]){ S [i]は= J。 ブレーク; } } } //ため(; iは= LEN <; I = int型1 ++ I)COUT << S [I] << ENDL。 F [0] [0] = 1。 I = 1をint型(ため。 以下のための(int型J = 1; IF(S [I]!= 0)F [i]は[J] =(([J] + F [I-1] F [I-1] [J-1] -f [S [I] -1- ] [J-1])MOD + MOD%)%MOD。 他[I] [J] =([I-1] [j]はF + F [I-1] [J-1])%MOD F。 } } のprintf( "%Dを\ n"、F [LEN] [L])。 0を返します。 }