[BZOJ3781]:小さなB(Moのチームアルゴリズム)を頼みます

トピックポータル


タイトル説明

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 ++

おすすめ

転載: www.cnblogs.com/wzc521/p/11239470.html