アイデアは確かに問題ではありませんが、TLEは2点を持っている理由を私は知りません -
#include <ビット/ STDC ++ H> の#define N 2000006 の#define setIO(S)freopenは(S ".IN"、 "R"、STDIN) 名前空間stdを使用。 マルチセット<整数> ID、LEN。 マルチセット<整数> ::イテレータit。 int型ARR [N]、ST [N]、長さ[N]、idxx [N]、N、M = 120。 文字列str [N]。 名前空間SA { INT RK [N]、[N] TP、税金[N]、SA [N]、高さ[N]、ログ[N]、DP [N] [22]。 ボイドのqsort() { ため(INT i = 0; I <= M; ++ I)税[I] = 0; ++税[RK [i]は];(; iが<= N I ++ iは1 = INT)のために (I 1 = int型; I <= M; ++ i)のための税金[I-1]〜[I] + =税。 SA [税[RK [i]は]] TP - ] = TPの[I] - (I; I> = 1、I = N INT)のために、 } ボイドコンストラクト() { RK [I] = I TP [I] =のARR [i]は、(; iが<= N I ++ iは1 = INT)のために qsort(); (int型のK = 1; = N <K; << = 1〜K)のための { INT P = 0。 TP [++ P] = I;(; iが<= N I ++ I = N-K + 1の整数)のために 以下のために(INT I = 1; I <= N; ++ I)IF(SA [I]> k)はTP [++のP] = SA [I] -k。 qsort()、スワップ(TP、RK)、RK [SA [1] = P = 1。 (; iが<= N I ++ I = 2 INT)ため RK [SA [I] =(TP [SA [I-1]] == TP [SA [I]] && TP [SA [I-1 ] + K] == TP [SAの[I] + K])P:++ P。 もし(P == n)をブレーク。 M = P。 } int型のk = 0。 (; iが<= N; iは1 = int型I ++)用RK [SA [I] = I。 (I 1 = int型、iが<= N; I ++)のために { あり、k - (k)の場合 INT J = SA [RK [I] -1]。 ながら(ARR [I + K] == ARR [J + K])++、K。 高さ[RK [I] = K。 } } ボイドRMQ() { (I = 2をint型++ I; iが<= N)+1でログイン[I] =ログイン[1 I >>]。 DP [I] [0] =高さ[I](; iが<= N I ++ i = 1 INT)のために、 (INT J = 1;(1 << J)<= N; ++ j)のための (; I +(1 << J)-1 <= N ++ iは1 = INT)のために 、DP [I] [ J] =分(DP [I]、[J-1]、DP [iが+(1 <<(j-1))] [J-1])。 } インラインINT getmin(INT A、INT B) { int型K =ログイン[B-A + 1]。 (DP [A] [K]、DP [B-(1 << K)+1] [K])分を返します。 } }。 INTメイン() { I、J、PP、NN、Q int型。 // setIO( "入力"); TMP = ST [X] + L-1。 scanf関数( "%d個"、 用(i = 1; iは= PP <; ++ I) { scanf関数( "%sの"、STR + 1)。 NNの=のSTRLEN(STR + 1)。 ST [I] = N + 1。 ; '+ 1 - ARR [++ N] = STR [J](; J <= NN ++ J J = 1)のために ARR [++ N] = 30。 } SA ::コンストラクト()。 SA :: RMQ(); scanf関数( "%のD"、&Q)。 用(i = 1; I <= Q; ++ I) { int型OPT。 scanf関数( "%d個"、&OPT)。 IF(OPT == 1) { int型、X、L、R、TMP。 scanf関数( "%D%D%D"、およびX、&L&R)。 id.insert(idxx [I])。 長さ[I] = R-L + 1。 len.insert(R-L + 1)。 INT A =(* id.begin())、B =(*( - id.end()))。 IF(A == B) { のprintf( "%d個の\ n"、* len.begin())。 } 他 { のprintf( "%d個の\ n"、分(* len.begin()、SA :: getmin(A + 1、B)))。 } } 他 { int型K。 scanf関数( "%のD"、&K); len.erase(len.lower_bound(長さ[K]))。 id.erase(id.lower_bound(idxx [K]))。 もし(len.empty()) { のprintf( "0 \ n"); 持続する; } INT A =(* id.begin())、B =(*( - id.end()))。 IF(A == B) { のprintf( "%d個の\ n"、* len.begin())。 } 他 { のprintf( "%d個の\ n"、分(* len.begin()、SA :: getmin(A + 1、B)))。 } } } 0を返します。 }