Submission #2093009


Source Code Expand

#include <bits/stdc++.h>

#define rep(i,n) for(int i=0; i<(n); i++)
#define reps(i,x,n) for(int i=x; i<(n); i++)
#define rrep(i,n) for(int i=(n)-1; i>=0; i--)
#define all(X) (X).begin(),(X).end()
#define X first
#define Y second
#define pb push_back
#define eb emplace_back

using namespace std;
typedef long long int ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }

template<class A, size_t N, class T> void Fill(A (&a)[N], const T &v){ fill( (T*)a, (T*)(a+N), v ); }

const ll INF = 1e17+7;


struct UnionFind{

	std::vector<int> data;
	// dataの各要素について
	// 負の値:その集合のルートであること示す。また、その絶対値は集合の要素数となっている。
	// 正の値:親ノードの番号(dataのインデックス)。root()を呼び出すたびに集合のルートを指すように書きなおされるので木はそんなに深くならない

	//初期化 size:最大要素数
	UnionFind(int size): data(size, -1) {}

	// 集合を併合する
	// すでに同じ集合だった場合は、falseが返る
	bool unite(int x, int y){
		x=root(x);
		y=root(y);
		if( x != y ){
			// 要素数の大きな方へ合併するためのswap
			if( data[y] < data[x] ) std::swap(x, y);
			// 要素数を加算する
			data[x] += data[y];
			// yの属する集合のルートをxに変更
			data[y] = x;
		}
		return x!=y;
	}

	// 同じ集合かどうか判定
	bool find(int x, int y){
		return root(x) == root(y);
	}

	// 集合の識別番号を返す
	int root(int x){
		// 負の値を持つものがその集合のルート
		// 正の値は同じ集合に属するものを指す(辿ればいずれルートへ着く)
		return (data[x] < 0)? x : data[x]=root(data[x]);
	}

	// 集合の要素数を返す
	int size(int x){
		return -data[ root(x) ];
	}
};

const ll MOD = 1e9+7;

// n^m%MOD を求める。O( log(m) )
ll modpow(ll n, int m){
	ll ret=1;
	for(int i=1; i<=m; i<<=1, (n*=n)%=MOD){
		if( m&i ) (ret *= n) %= MOD;
	}
	return ret;
}

// 逆元を求める
ll modinv(ll n){
	return modpow( n, MOD-2 );
}

// 階乗を求める。O(1)  準備O( n*log(n) )
// fact[n]     : nの階乗
// fact.inv[n] : nの階乗の逆元
class FACTORIAL{
public:
	vector<ll> fact, inv;
	FACTORIAL(int MAX_NUM): fact(MAX_NUM), inv(MAX_NUM) {
		fact[0] = inv[0] = 1;
		for(ll i=1; i<MAX_NUM; i++){
			fact[i] = (fact[i-1] * i) % MOD;
			inv[i] = modinv( fact[i] );
		}
	}
	const ll& operator [ ] ( const int i ) const {
		return fact[i];
	}
} fact(1000006); // nの最大値を指定


// 組み合わせ(Combinationを求める) O(1)
ll cmb(unsigned int n, unsigned int r){
	if( n < r ) return 0;
	return fact[n] * fact.inv[r] % MOD * fact.inv[n-r] % MOD;
}

int main(){
	ios_base::sync_with_stdio(false);
	ll N, X, Y;
	ll c[200005], w[200005];

	cin >> N >> X >> Y;
	rep(i,N){
		cin >> c[i] >> w[i];
		c[i]--;
	}

	pll mn[200005];
	Fill(mn, pll(INF,-1));
	rep(i,N) chmin(mn[ c[i] ], pll(w[i], i));

	UnionFind uf(200005);

	vector<pll> v;
	rep(i,N) if( mn[i].Y >= 0 ) v.push_back( mn[i] );
	sort(all(v));
	reps(i,1,v.size()){
		if( v[i-1].X + v[i].X <= Y ) uf.unite(v[i-1].Y, v[i].Y);
	}

	rep(i,N){
		auto p = c[i];
		if( mn[p].X + w[i] <= X ) uf.unite(mn[p].Y, i);
		if( c[ v[0].Y ] != p ){
			if( v[0].X + w[i] <= Y ) uf.unite(v[0].Y, i);
		}else if( v.size() > 1 ){
			if( v[1].X + w[i] <= Y ) uf.unite(v[1].Y, i);
		}
	}

	ll ans = 1;
	rep(i,N) if(uf.root(i) == i){
		ans *= fact[ uf.size(i) ];
		ans %= MOD;
	}

	map<pll,ll> count;
	{
		//ll count[200005]={};
		rep(i,N) count[ pll(uf.root(i),c[i]) ]++;

		//rep(i,N) if( count[i] > 1 ){
		for(auto p: count){
			ans *= fact.inv[ p.Y ];
			ans %= MOD;
		}
	}

	cout << ans << endl;

	return 0;
}

Submission Info

Submission Time
Task D - Colorful Balls
User oyas
Language C++14 (GCC 5.4.1)
Score 1000
Code Size 4048 Byte
Status AC
Exec Time 311 ms
Memory 38764 KB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 1000 / 1000
Status
AC × 3
AC × 57
Set Name Test Cases
Sample 00_example_01.txt, 00_example_02.txt, 00_example_03.txt
All 00_example_01.txt, 00_example_02.txt, 00_example_03.txt, 01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, 24.txt, 25.txt, 26.txt, 27.txt, 28.txt, 29.txt, 30.txt, 31.txt, 32.txt, 33.txt, 34.txt, 35.txt, 36.txt, 37.txt, 38.txt, 39.txt, 40.txt, 41.txt, 42.txt, 43.txt, 44.txt, 45.txt, 46.txt, 47.txt, 48.txt, 49.txt, 50.txt, 51.txt, 52.txt, 53.txt, 54.txt
Case Name Status Exec Time Memory
00_example_01.txt AC 172 ms 21760 KB
00_example_02.txt AC 172 ms 21376 KB
00_example_03.txt AC 172 ms 22016 KB
01.txt AC 172 ms 20864 KB
02.txt AC 172 ms 21376 KB
03.txt AC 175 ms 22656 KB
04.txt AC 173 ms 22656 KB
05.txt AC 174 ms 22144 KB
06.txt AC 172 ms 22016 KB
07.txt AC 217 ms 26996 KB
08.txt AC 172 ms 22528 KB
09.txt AC 187 ms 22016 KB
10.txt AC 184 ms 23296 KB
11.txt AC 173 ms 22656 KB
12.txt AC 172 ms 21760 KB
13.txt AC 175 ms 21504 KB
14.txt AC 172 ms 22400 KB
15.txt AC 193 ms 24440 KB
16.txt AC 213 ms 28276 KB
17.txt AC 177 ms 21888 KB
18.txt AC 187 ms 22912 KB
19.txt AC 204 ms 24960 KB
20.txt AC 286 ms 34672 KB
21.txt AC 277 ms 36336 KB
22.txt AC 275 ms 36080 KB
23.txt AC 291 ms 34160 KB
24.txt AC 264 ms 37232 KB
25.txt AC 285 ms 34032 KB
26.txt AC 291 ms 33776 KB
27.txt AC 269 ms 33008 KB
28.txt AC 295 ms 33776 KB
29.txt AC 289 ms 34416 KB
30.txt AC 259 ms 37360 KB
31.txt AC 302 ms 33648 KB
32.txt AC 278 ms 35312 KB
33.txt AC 295 ms 34032 KB
34.txt AC 311 ms 32112 KB
35.txt AC 236 ms 25600 KB
36.txt AC 249 ms 26108 KB
37.txt AC 239 ms 25600 KB
38.txt AC 237 ms 25728 KB
39.txt AC 240 ms 25728 KB
40.txt AC 267 ms 33648 KB
41.txt AC 276 ms 36204 KB
42.txt AC 271 ms 37356 KB
43.txt AC 266 ms 37740 KB
44.txt AC 277 ms 36716 KB
45.txt AC 262 ms 38764 KB
46.txt AC 274 ms 35180 KB
47.txt AC 239 ms 27136 KB
48.txt AC 271 ms 30976 KB
49.txt AC 251 ms 28416 KB
50.txt AC 230 ms 30704 KB
51.txt AC 249 ms 30704 KB
52.txt AC 227 ms 28160 KB
53.txt AC 227 ms 28160 KB
54.txt AC 227 ms 28160 KB