ARC084 C : Snuke Festival(300)

作成日:2017.11.05
最終更新日:2017.11.05

問題概要

問題本文

 上部、中部、下部の3つのパーツからなる祭壇を作る。 各部位のパーツはそれぞれ$N$個ずつあり、大きさは順に$A_i$,$B_i$,$C_i$である。 祭壇は$A_x$$< B_y$$< C_z$となるパーツを組み合わせることでのみ作ることができる。 この時、作ることができる祭壇は何種類あるか求めよ。
制約
$1 \leq N \leq 10^5$
$1 \leq A_i , B_i , C_i \leq 10^9$
入力はすべて整数

考え方

 $A$と$B$の2つのパーツだけがある場合を考える。 この時$A_i$を決めると条件を満たす$B_j$の個数は$O(N)$で求められる。 このままだと全体で$O(N^2)$となり間に合わないが、$A$,$B$をともにソートするとポインタを一方向にのみ進めれば良くなることから$O(N)$で求められるようになる。
 元の問題に戻ると、$B$を固定するごとに条件を満たす$A$及び$C$の個数を求めてその積の総和を求めれば良い。 これは先に考えたものと同様にすることで$O(N)$で求めることができる。

ソースコード

マクロ等はこちら

const int MC = 100010;
int N;
int A[MC],B[MC],C[MC];
LL ansB[MC];
LL ans;

int main(){
	cin >> N;
	repp(i,0,N) cin >> A[i];
	repp(i,0,N) cin >> B[i];
	repp(i,0,N) cin >> C[i];
	A[N] = B[N] = C[N] = 1e9 + 7;
	sort(A,A+N);
	sort(B,B+N);
	sort(C,C+N);
	int x = 0 , z = 0;
	repp(i,0,N){
		while(A[x] < B[i]) ++x;
		while(C[z] <= B[i]) ++z;
		ans += (LL)x * (N-z);
	}
	cout << ans << endl;
	return 0;
}

解法まとめ

 $A$,$B$,$C$をソートし、$B$を固定するごとに条件を満たす$A$の個数と$C$の個数の積を求めて答えに加算する。(13-21行)

ARC084の他の問題 D E F

自己紹介

プログラミングとか合成音声とか
詳しくはこちら
twitter

プライバシーポリシー

個人情報利用についてはこちら

最終更新日:2023.03.05

お問い合わせ

このページに関するお問い合わせはこちら

競技プログラミングMENU

問題を解くまでの道のり

その他

全体MENU

寄付モドキ

0冂から10000冂まで
詳しくはこちら