タイトル説明
人々の規律の人生として、小さなZ毎朝着用するカラフルな靴下の山から1ペアを見つけるのに長い時間がかかります。
最後に1日、小さなZはもはや靴下を見つけるために、この迷惑なプロセスを容認することはできませんので、彼は運命に決めました。
具体的には、これらの小さなZのN靴下は1からNまでの番号、およびRソックス内の2つのランダムに選択された数Lから着用します。
小さなZは、靴下の2ペアを気にしないにもかかわらず、でも2枚の靴下は、非常に恥ずかしいだろう二つの異なる色の靴下を履いて、どちらかの側には、彼は結局靴下の色、非常に心配であるかどうかを気にしない、完全ではありません。
あなたの仕事は、彼が2色の靴下の同じ確率を取得することができますどのように古い、小さなZを伝えることです。
もちろん、小さなZは、可能な限りそれは、この確率の高い願っていたので、彼は、彼らの選択を容易にするために、より多くの(L、R)を求めることができます。
入力形式
最初の行は、2つの正の整数NおよびMが含まれ、Nは、Mは、Zは、問い合わせに言及小さい、靴下の数です。
次の行は、nは正の整数含有するC IのCI、C iは色を示すi番目の靴下のCI、同じ番号で表される同じ色を。
次のM行は、各列2つの正の整数L、Rは、クエリを表します。
出力フォーマット
M行、に呼び掛け区間[L、R]から同じ2つのランダムに色確率靴下を表し/ Bの行Aの各呼掛け出力スコアを含みます。
確率は0 0/1出力であれば、そうでない場合はA / Bの出力は、最も簡単な分数でなければなりません。
データ範囲
N、M≤50000、
1≤L<R≤N、
Ci≤N
サンプル入力:
6 4
1 2 3 3 3 2
2 6
1 3
3 5
1 6
出力例:
2/5
0/1
1/1
4/15
溶液:この問題は、間隔求め[Lを、R]は無作為に2つの靴下を必要と同じ数の要素に対応する同一の色確率間隔を選択しました。私たちは、Moのチームで行うことができます。最初のオフラインアルゴリズムである、ブロックに分割されている「尋ねる」の:間隔を読み取るために問い合わせまず、次いで、ブロック(√Nにブロック)、ソートの右端左端ポイントに従ってソート。なぜ、左のポイントはYaoanブロックは、ソートの代わりに、直接それを注文するのですか?あなたが小から大に左のポイントを押した後、大量の注文に小さな右のスポットを押すと、その左の点が単調で移動しますが、変更の右のポイントを決定することができません。タップ・オーダリング・ブロックは放置し、その後吐出ポイントの右端には、その後、範囲√N内モノトーンの右端を左隣り合う呼び掛け点を変更します。これは明らかに優れています。タイトルを更新しながら、その後、我々は無作為に2つを求めている、左端点Lに1つのポインティング、常に右の点R、問合せ部の移動に応じて2つのポインタ、およびポイントは、各要素の数L〜R間隔を更新し、二つのポインタを定義しますこの間隔は、ポイントの数について再度無作為に選択された二靴下の数で割った後に同じ色の靴下の数だけ、各音符間隔は、この質問に回答する場合です。
1.ポインタが移動したことを注意して値を更新する場合:二つのことに注意してください。
2.注コンタクト変換。
コード:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 #defineっ長い長 のconst int型 N = 50000 + 10 。 INT [N]、[N]を事前。 構造体ノード{ int型のID、L、R。 LL X、Y。 ブール 演算子 <(constのノード&T)のconst { 場合(予備[L] ==事前[TL])戻り R < TR。 戻りプレ[L] < 予備[TL]を。 } }、Q [N]。 ブールCMP(ノードI、ノードj){ 戻り i.id <j.id; } LL NUM [N]。 LLのGCD(-1,11,11- b)は{ 戻り B GCD(B、%の?B)。 } int型のmain(){ int型、N M。 scanf関数(" %d個の%のD "、&N、&M)。 INT K = SQRT(N)。 以下のために(int型 i = 1 ; iが<= N; iが++ ){ scanf関数(" %dを"&[I])。 [i]は予め = I / Kと、 } のための(int型 I = 0 ; iが<M、I ++は){ scanf関数を(" %dの%のD "、&Q [i]は.L&Q [I] .R)。 Q [i]は.ID = iは、 } ソート(Q、Q + M)。 INTは L = 1、R = 0 。 FZ LL = 0、FM = 0 。 以下のために(int型 i = 0 ; iがm <; iは++ ){ 場合(Q [i]が.L == Q [I] .R){ Q [i]が.X = 0 。 Q [i]は.Y = 1 。 引き続きながら、 ; } (R < Q [I] .R){ R ++ 。 FZ - = NUM [[R]] *(NUM [[R]] - 1 )。 NUM [[R]] ++ ; FZ + = NUM [[R]] *(NUM [[R]] - 1 )。 } 一方、(R> Q [i]は.R){ FZ - = NUM [[R]] *(NUM [[R]] - 1 )。 NUM [[R]] - 。 FZ + = NUM [[R]] *(NUM [[R]] - 1 )。 R - ; } 一方、(L < Q [I] .L){ FZ- NUM = [A [L]] *(NUM [A [L]] - 1。); NUM [A [L]] - ; FZ + NUM = [L]] *(NUM [A [L] ] - 1。); L ++ ; } ながら(L> Q [I] .L){ L - ; FZ - NUM = [L]] *(NUM [A [L]] - 1。); NUM [A [L]] ++ ; FZ + NUM = [A [L]] *(NUM [A [L]] - 1 ); } FM =(LL)(+ RL 1)*(RL)/ / 型変換を忘れます。。WA数ラウンド LLのTF = GCD(FZ、FM)。 Q [i]は.X = FZ / TF。 Q [i]は.Y = FM / TF。 } ソート(Q、Q + M、CMP)。 以下のために(int型 i = 0 ; iがmを<; iは++ ) のprintf(" %LLD /%LLD \ n " 、Q [i]は.X、Q [i]の.Y)。 リターン 0 ; }