問題の意味
要求間隔期間の少なくとも2倍の数の数が発生します。
保証N- 、M 、C ≤ 2 * 1 0 。6、範囲C
問題の解決策
私はこのアイデアは、それのノートの価値があることを、少し馴染みのを感じ、そして後にHHのネックレスバリアント詩授業時間について話しました。
最初のチームの練習は、操作が非常に簡単で、Moのですが、時間外。
彼は3倍以上が含まれている第一の位置が登場すると、それがあるため、巧妙なアイデアは、数は少なくとも二回表示された場合、彼は二度目の登場ところ、我々は唯一気に、同じクエリのための右の終点である比較彼が含まれている必要がありますが、2つだけ貢献することができ、より多くの貢献は増加しません。
第二の数のために、アレイとして確立された配列位置のインデックスツリーは、この位置+1では、右から左に発生します。
右側のエンドポイントと、クエリ、および範囲クエリの場合はそれがあります。
初めて数が第2の発生回数、のための位置+1になる前;右端点が移動したとき、この数は番号が最初に現れるとなる第二の数の発生前に、その彼は第三の外観がこの位置-1に寄与しないとなりました。
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 const int型 MAXN = 2000005 ; INTのN、M、C。 int型POS [MAXN]、サイズ; INT CO [MAXN]、モミ[MAXN]、秒[MAXN]。 int型 CX [MAXN << 1 ]。 int型ANS [MAXN]。 構造体質問{ int型のL、R、ID。 } Q [MAXN]。 テンプレート < クラス T>インラインボイドリード(T&X){ X = 0。チャー CH = GETCHAR()。 しばらく(!isdigit(CH))CH =getchar関数(); 一方、(isdigit(CH)){X =(X << 1)+(X << 3)+(CH ^ 48)、CH = GETCHAR();} } BOOL CMP(質問A、質問B){ 戻り AR < BR;} ボイド追加(int型のx、int型のval){ ため(; X <= Nであり、X + = X&-x)CX [X] + = ヴァル;} int型クエリ(INT X){ int型 RET = 0 。 用(; X; X - = X&-x)RET + = CX [X]。 リターンRET; } int型のmain(){ (n)を読み出す;(c)を読み出す;(m)を読み出します。 以下のために(int型 i = 1 ; iが<= N; iは++ )読み出す(CO [I])。 用(int型 iは= 1 {読み出す(Q [i]の.L);読み取る(Q [i]の.R); Q [i]を.ID =; I <= M iは++)I;} ソート(Q + 1、Q + M + 1 、CMP)。 int型 J = 1 ; 以下のために(int型 i = 1 ; iは= N <; iは++ ){ 場合(FIR [CO [I]]!)// 这个数之前没出现 FIR [CO [I] = I。 それ以外の 場合(!秒[コ[I]]){ // 只有一个 [コ[I]]、モミ(追加1); 秒[CO [I] = モミ[CO [I]]。 FIR [CO [I] = I。 } 他 { // 出现了两次以上 追加(SEC [CO [I]] - 1 )。 追加(FIR [CO [I]、1 )。 秒[CO [I] = モミ[CO [I]]。 FIR [CO [I] = I。 } ながら(Q [J] .R == i)は、[Qは[J] .ID] ANS =クエリ(Q [J] .R)-query(Q [J] .l- 1)、J ++ 。 } のための(int型 I = 1 ; I <= M; iが++)のprintf(" %d個の\ n " 、ANS [I])。 }