답안 #709407

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
709407 2023-03-13T14:09:31 Z denniskim Fish (IOI08_fish) C++17
100 / 100
877 ms 63700 KB
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef __int128 lll;
typedef long double ld;
typedef pair<ll, ll> pll;
#define MAX 9223372036854775807LL
#define MIN -9223372036854775807LL
#define INF 0x3f3f3f3f3f3f3f3f
#define fi first
#define se second
#define fastio ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cout << fixed; cout.precision(10);
#define sp << " "
#define en << "\n"
#define compress(v) sort(v.begin(), v.end()), v.erase(unique(v.begin(), v.end()), v.end())

ll n, K;
ll ss;
pll a[500010];
vector<ll> w[500010];
pll tmp[500010];
ll idx[500010];
ll ans;
ll p;

struct segtree
{
	ll seg[2000010];
	
	void init(ll no, ll s, ll e)
	{
		seg[no] = 1;
		
		if(s == e)
			return;
		
		init(no << 1, s, (s + e) >> 1);
		init(no << 1 | 1, ((s + e) >> 1) + 1, e);
	}
	
	void update(ll no, ll s, ll e, ll w, ll v)
	{
		if(e < w || w < s)
			return;
		
		if(s == e)
		{
			seg[no] = (seg[no] + v) % ss;
			return;
		}
		
		ll mid = (s + e) >> 1;
		
		update(no << 1, s, mid, w, v);
		update(no << 1 | 1, mid + 1, e, w, v);
		
		seg[no] = seg[no << 1] * seg[no << 1 | 1] % ss;
	}
	
	ll query(ll no, ll s, ll e, ll l, ll r)
	{
		if(e < l || r < s || e < s)
			return 1;
		
		if(l <= s && e <= r)
			return seg[no];
		
		ll mid = (s + e) >> 1;
		
		return (query(no << 1, s, mid, l, r) * query(no << 1 | 1, mid + 1, e, l, r)) % ss;
	}
}segt;

int main(void)
{
	fastio
	
	cin >> n;
	cin >> K;
	cin >> ss;
	
	for(ll i = 1 ; i <= n ; i++)
		cin >> a[i].fi >> a[i].se;
	
	sort(a + 1, a + 1 + n);
	
	for(ll i = 1 ; i <= n ; i++)
		w[a[i].se].push_back(i);
	
	for(ll i = 1 ; i <= K ; i++)
		tmp[i] = {w[i].back(), i};
	
	sort(tmp + 1, tmp + 1 + K);
	
	for(ll i = 1 ; i <= K ; i++)
		idx[tmp[i].se] = i;
	
	segt.init(1, 1, K);
	
	p = 1;
	
	for(ll i = 1 ; i <= n ; i++)
	{
		while(p <= n && a[p].fi * 2 <= a[i].fi)
		{
			segt.update(1, 1, K, idx[a[p].se], 1);
			p++;
		}
		
		if(w[a[i].se].back() == i)
		{
			//cout << a[i].fi sp << a[i].se en;
			
			ll W = 0;
			ll l = 0, r = (ll)w[a[i].se].size() - 2;
			
			while(l <= r)
			{
				ll mid = (l + r) >> 1;
				
				if(a[w[a[i].se][mid]].fi * 2 <= a[i].fi)
					l = mid + 1;
				else
					r = mid - 1;
			}
			
			W = w[a[i].se][r + 1];
			
			ll gg = r + 1;
			//cout << "W" << a[W].fi sp << a[W].se en;
			l = idx[a[i].se] + 1;
			r = K;
			
			while(l <= r)
			{
				ll mid = (l + r) >> 1;
				
				if(a[W].fi * 2 <= a[tmp[mid].fi].fi)
					r = mid - 1;
				else
					l = mid + 1;
			}
			
			ll gap = segt.query(1, 1, K, 1, idx[a[i].se] - 1);
			gap = gap * segt.query(1, 1, K, idx[a[i].se] + 1, r) % ss;
			
			//cout << "First query : " << gap en;
			ans = (ans + gap) % ss;
			
			W = w[a[i].se][0];
			l = idx[a[i].se] + 1;
			r = K;
			
			while(l <= r)
			{
				ll mid = (l + r) >> 1;
				
				if(a[W].fi * 2 <= a[tmp[mid].fi].fi)
					r = mid - 1;
				else
					l = mid + 1;
			}
			
			segt.update(1, 1, K, idx[a[i].se], -1);
			gap = segt.query(1, 1, K, 1, r);
			segt.update(1, 1, K, idx[a[i].se], 1);
			
			if(!gg)
				gap = 0;
			
			//cout << "Second query : " << gap en;
			ans = (ans + gap) % ss;
			
			//cout << ans en;
		}
	}
	
	ans = ans % ss < 0 ? ans % ss + ss : ans % ss;
	
	cout << ans;
	return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 11988 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 12116 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 12072 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 12016 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 12116 KB Output is correct
2 Correct 7 ms 12116 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 12116 KB Output is correct
2 Correct 159 ms 30376 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 12116 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 12264 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 68 ms 20176 KB Output is correct
2 Correct 90 ms 21988 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 12244 KB Output is correct
2 Correct 12 ms 12340 KB Output is correct
3 Correct 9 ms 12244 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 115 ms 23316 KB Output is correct
2 Correct 198 ms 31340 KB Output is correct
3 Correct 189 ms 32048 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 187 ms 28072 KB Output is correct
2 Correct 175 ms 33240 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 104 ms 23288 KB Output is correct
2 Correct 209 ms 32392 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 184 ms 26744 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 236 ms 29800 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 202 ms 27136 KB Output is correct
2 Correct 304 ms 39576 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 496 ms 37000 KB Output is correct
2 Correct 404 ms 34732 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 405 ms 37452 KB Output is correct
2 Correct 440 ms 39556 KB Output is correct
3 Correct 430 ms 43940 KB Output is correct
4 Correct 468 ms 39588 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 626 ms 39556 KB Output is correct
2 Correct 719 ms 62712 KB Output is correct
3 Correct 672 ms 63700 KB Output is correct
4 Correct 877 ms 58416 KB Output is correct