トピックポータル
タイトル説明
Bは、小さな配列が$ N $ 1~ $ K $の間の整数が含まれています。彼は$ \和の\ limits_ {i = 1} ^ {K} C(I)$の^ 2値を求め、$ M $の合計、各質問所定の間隔$ [のL ... R] $を依頼しますここでの$ C(I)$ $ I $ $の内数を表し、[Lを... R]は繰り返しの数を$。小型の$ B $は、彼は質問に答えるためにあなたを招待します。
入力形式
最初の行、三つの整数N、M、K.
第二行、Nの整数、Bは、小の配列を表します。
次のM行は、各行二つの整数L、R.
出力フォーマット
M線、整数i番目の回答問い合わせのi番目の行を表す整数、それぞれ。
サンプル
サンプル入力
6 4 3
1 3 2 1 3
1 4
2 6
3 5
5 6
サンプル出力
6
9
5
2
データ範囲とヒント
すべてのデータのために、$ 1 \ leqslant N、Mは、K \ 50,000 $をleqslant。
問題の解決策
それを発見するハッピーオフラインを必要とし、$ $ 50,000範囲のデータを、よりリラックスしたので、Moのチームを考えます。
最初のシーケンスブロックし、その後は常にエンドポイントの周りに伸ばし、ソートを聞いて、十分に間違えないように注意してください。
私は本当にもう言うことかわからない......
コードの時間
#include <ビット/ STDC ++ H>
名前空間STDを使用して、
構造体REC
{
int型のID。
int型のL;
int型のR;
int型のPOS。
} Q [50001]。
[50001] int型。
int型CNT [50001];
長い長いANS;
長い長い合計[50001];
ブールCMP(REC B、REC){a.pos戻り== b.pos AR <BR:a.pos <b.pos;} //排序
INTのmain()
{
int型N、M、K。
scanf関数( "%D%D%D"、&N、&M、およびK);
INT、T = SQRT(N); //分块
ため(INT I = 1; I <= N; iが++)
scanf関数を( "%のD"、および[I])。
以下のために(INT I = 1; I <= M; iは++)
{
scanf関数( "%d個の%のD"、&Q [i]は.L&Q [I] .R)。
Q [i]はiは= .ID。
Q [i]は.POS =(Q [i]が.L-1)/ T + 1。
}
INT 1 = 1、R = 0。
以下のために(INT I = 1; I <= M; iは++)//四种情况伸缩左右端点
{
一方(L <Q [i]が.L)
{
ans- = 2 * CNT [[L]] - 1。 //注意答案的加减
CNT [L] - 。
L ++;
}
一方、(L> Q [I] .L)
{
l--。
ANS + = 2 * CNT [[L] + 1。
CNT [L]] ++;
}
一方、(R <Q [i]は.R)
{
R ++。
ANS + = 2 * CNT [[R]] + 1。
CNT [[R]] ++;
}
一方、(R> Q [i]は.R)
{
ans- = 2 * CNT [[R]] - 1。
CNT [[R]] - 。
r--の;
}
和[Q [i]は.ID] =のANS。
}
ため(INT I = 1; I <= M; iは++)
のprintf( "%LLDする\ n"、和[I])。
0を返します。
}
RP ++