この問題は、本当にショーです。。。私がしなければなりませんでした。。。書くことができるものの良い感じでセグメントツリー。。。
トピックの効果は:各番号について、またはKの発生よりも、この子が持っていたノーショーの文字列、またはそれ以上:あなたの文字列を与えるために、サブストリングが最も長いが長い、以下の条件を満たすように尋ねました。
私たちは、私は、確かに遠いが、条件を満たすために、左見つけることを願っていますそれぞれの場所には、最大ではなく、宮を維持尊重しますか?
だから、どのように我々は、最も遠いが条件を満たして見つけるのですか???それでは、私たちはいくつかのものを維持する必要がありますか?
我々は、[] T配列を維持し、T [J] = M iは位置jから左へのビットを表し、条件満足する数メンテナンスセグメントツリー、(いずれか0として、kは1以上です)。
私は、我々が現在の位置にC-1を追加する必要がある各位置、現在の代表点、区間0の長さ
場合右点、他の数は、Xの左の点を除いて、私はのように[I、i]は、この範囲の位置とすることができるように、我々はTを議論するたびに[i]は、[I] = xとして、Iの位置でありますxは、他の人が0回登場している、一度だけ以内に現れ0は確かに可能である現れ、第1プラスC-1(-1位置ので、私はさらに、生存可能な左点Xとして議論する必要がある場合)
その後、我々は数によるi番目の場所に[i]は私の位置は、位置および位置の値に等しく[i]を、可能にするために使用間隔に[i]は、次いで得られた現在位置が登場検討しますしかし、今になっていません。私たちは、必要とします
一つの位置から-1の完全な値、[i]は、間隔が利用可能でなくなったの代表です。そして、私たちの前方にkの現在の位置から[i]のK-1 [i]の位置より前の位置で、前回の位置は使用できませんが、右側の[i]は、新規に追加されますので、このセクションでは利用できないが利用可能になるであろう、それは元の値を表す、+1の範囲内であるべきであるが、利用できない現在利用可能です。
#include <ビット/ STDC ++ H> に#define LL長い長 の#define LSONのRT << 1つ の#define rsonのRT << 1 | 1 使用して 名前空間STDを、 const int型 MAXX = 1E5 + 6 。 構造体ノード{ int型のL、R。 int型、CNTを過ごします。 }ツリー[MAXX << 2 ]。 INT [MAXX]。 INT 前[MAXX]。 int型N、C、K。 ベクター < INT > G [MAXX]。 ボイド push_down(INT RT){ 場合(ツリー[RT] .laze){ ツリー[LSON] .CNT + =ツリー[RT] .laze。 ツリー[rson] .CNT + = ツリー[RT] .laze。 ツリー[LSON] .laze + = ツリー[RT] .laze。 ツリー[rson] .laze + = ツリー[RT] .laze。 ツリー[RT] .laze = 0 。 } } ボイド buildtree(INT RT、INT L、INT R){ ツリー[RT] .L = L。 ツリー[RT] .R = R。 ツリー[RT] .laze = 0 。 ツリー[RT] .CNT = 0 。 もし(L == R){ 。リターン } INT半ば=(L + R)>> 1 。 buildtree(LSON、L、MID)。 buildtree(rson、ミッド + 1 、R)。 } ボイド更新(INT RT、INT UL、int型 UR、INT W){ int型 L = ツリー[RT] .L。 INT R = ツリー[RT] .R。 もし(UL <= 1 && R <= UR){ ツリー[RT] .CNT + = W。 ツリー[RT] .laze + = W。 返します。 } push_down(RT)。 INT半ば=(L + R)>> 1。 もし(UR <= MID){ 更新(LSON、UL、UR、W)。 } そう であれば(UL> MID){ 更新(rson、UL、UR、W)。 } 他{ 更新(LSON、UL、中、W)。 アップデート(rson、ミッド + 1 、UR、W)。 } ツリー[RT] .CNT = MAX(ツリー[LSON] .CNT、ツリー[rson] .CNT)。 } INTクエリ(INT RT){ int型 L = ツリー[RT] .L。 INT R = ツリー[RT] .R。 もし(1- ==のR){ 戻りL。 } push_down(RT); INT半ば=(L + R)>> 1 。 もし(ツリー[LSON] .CNT == C){ 戻りクエリ(LSON)。 } そう であれば(ツリー[rson] .CNT == C){ 戻りクエリ(rson)。 } 他{ リターン - 1 。 } } int型のmain(){ しながら(〜のscanf(" %D%D%D "、&N、&C&K)){ ため(int型 i = 1 ; iが= Cを<; iは++ ){ G [i]が.clear(); G [i]が.push_back(0 )。 } のmemset(前、0、はsizeof (PRE))。 以下のために(int型 i = 1 ; iが<= N; iが++ ){ scanf関数(" %dを"&[I])。 G [I]一back(I)。 } buildtree(1、1 、N) もし(Kの== 1 ){ のprintf(" %d個の\ n " 、N)。 続け; } INT ANS = 0 。 以下のために(int型 i = 1 ; iが<= N; iは++ ){ int型のx = [I]。 int型のp = ++ プリ[[I]]; アップデート(1、I、I、C- 1 )。 もし(G [I] [P- 1 ] + 1 <= G [I]、[P] - 1 ) アップデート(1、G [I] [P- 1 ] + 1、 G [I]、[P] - 1 - 1 )。 もし(P> = k)を 更新(1、G [I] [PK] + 1、G [I] [P-K + 1 ]、1 )。 INT POS =クエリ(1 )。 もし(POS =! - 1 ){ ANS = MAX(ANS、I-POS + 1 )。 } } のprintf(" %d個の\ n " 、ANS)。 } 戻り 0 。 }