Problem:
イベント巡り
IOI 国には
2
個の町があり，それぞれ
1, 2
と番号がついている．
これらの町では合計
N
個のイベントが行われる．これらのイベントには
1
から
N
までの番号がついている．イベント
i
(
1 ≦ i ≦ N
) は町
P
i
で開催され，開催時刻は時刻
S
i
+ 0.1
から時刻
S
i
+ 0.9
までである．ここで
S
i
は整数である．JOI 君がイベント
i
に参加するためには，時刻
S
i
+ 0.1
から時刻
S
i
+ 0.9
までの間，ずっと町
P
i
にいる必要がある．
JOI 君はイベント巡りを行うことにした．イベント巡りではいくつかのイベントに参加し，必要ならば町と町の間を移動することもできる．JOI 君は時刻
0
からイベント巡りを開始する．このとき，好きな町から始めることができる．
JOI 君は町
1
と町
2
の間を双方向に移動することができる．
2
つの町の間を移動するのにかかる時間は，JOI 君がその移動を開始する時刻までに参加したイベントの数を
j
として，
D + K × j
となる．
イベントと町の間の移動に関する情報が与えられるので，JOI 君が参加できるイベントの数の最大値を求めるプログラムを作成せよ．
制約
1 ≦ N ≦ 200000
．
1 ≦ D ≦ 10
12
．
0 ≦ K ≦ 10
12
．
1 ≦ P
i
≦ 2
(
1 ≦ i ≦ N
)．
1 ≦ S
i
≦ 10
12
(
1 ≦ i ≦ N
)．
S
i
≠ S
j
(
1 ≦ i < j ≦ N
)．
入力される値はすべて整数である．
入力
入力は以下の形式で標準入力から与えられる．
N
D
K
P
1
S
1
P
2
S
2
:
P
N
S
N
出力
標準出力に，JOI 君が参加することのできるイベントの数の最大値を
1
行で出力せよ．
入出力例
入力例 1
5 3 0
1 1
1 2
1 10
2 5
2 6
出力例 1
4
例えば，以下のように行動することで，JOI 君は
4
個のイベントに参加することができる．
時刻
0
において JOI 君は町
1
にいる．
時刻
1.1
から時刻
1.9
まで町
1
でイベント
1
に参加する．
時刻
2.1
から時刻
2.9
まで町
1
でイベント
2
に参加する．
時刻
3
から時刻
6
まで時間
3
(
= D + K × 2
) をかけて町
1
から町
2
に移動する．
時刻
6.1
から時刻
6.9
まで町
2
でイベント
5
に参加する．
時刻
7
から時刻
10
まで時間
3
(
= D + K × 3
) をかけて町
2
から町
1
に移動する．
時刻
10.1
から時刻
10.9
まで町
1
でイベント
3
に参加する．
どのように行動しても
5
個以上のイベントに参加することはできないため，
4
を出力する．
入力例 2
7 2 3
2 2
1 8
1 10
1 11
2 23
2 24
2 25
出力例 2
6
例えば，以下のように行動することで，JOI 君は
6
個のイベントに参加することができる．
時刻
0
において JOI 君は町
2
にいる．
時刻
2.1
から時刻
2.9
まで町
2
でイベント
1
に参加する．
時刻
3
から時刻
8
まで時間
5
(
= D + K × 1
) をかけて町
2
から町
1
に移動する．
時刻
8.1
から時刻
8.9
まで町
1
でイベント
2
に参加する．
時刻
11.1
から時刻
11.9
まで町
1
でイベント
4
に参加する．
時刻
12
から時刻
23
まで時間
11
(
= D + K × 3
) をかけて町
1
から町
2
に移動する．
時刻
23.1
から時刻
23.9
まで町
2
でイベント
5
に参加する．
時刻
24.1
から時刻
24.9
まで町
2
でイベント
6
に参加する．
時刻
25.1
から時刻
25.9
まで町
2
でイベント
7
に参加する．
どのように行動しても
7
個以上のイベントに参加することはできないため，
6
を出力する．
入力例 3
12 153 0
1 155
2 861
1 646
1 218
2 450
2 56
1 932
2 295
2 863
1 612
2 38
2 768
出力例 3
8
入力例 4
15 89 104
1 4379
1 738
1 4862
1 4236
2 1416
1 9905
1 4775
2 4574
2 439
1 3956
1 955
2 8862
2 801
2 2299
2 575
出力例 4
11
情報オリンピック日本委員会
作 『第 20 回日本情報オリンピック JOI 2020/2021 二次予選競技課題』

Submitted solutions:

code_snippet: #include <iostream>
#include <set>
#include <algorithm>
#include <string.h>
using namespace std;

long long int dp[200010][2][2];
std::set<long long int> ss[2];

int main() {
	long long int n,d,k1;
	cin>>n>>d>>k1;
	for(int i=0;i<n;i++){
		long long int s1,t1;
		cin>>s1>>t1;
		ss[s1-1].insert(t1);
	}
	memset(dp,-1,sizeof(dp));
	dp[0][0][0]=0;
	dp[0][1][0]=0;
	dp[0][0][1]=0;
	dp[0][1][1]=0;
	int ans=0;
	for(int i=0;i<=n;i++){
		for(int j=0;j<2;j++){
			for(int k=0;k<2;k++){
				long long int t0=dp[i][k][j];
				if(t0==-1)continue;
				long long int t1=0;
				if(j==k){
					t1=t0;
				}else{
					t1=t0+d+i*k1;
				}
				auto it=ss[k].lower_bound(t1);
				if(it==ss[k].end()){
					if(ans<i)ans=i;
				}else{
					long long int ta,tb;
					ta=dp[i+1][0][k];
					tb=dp[i+1][1][k];
					if(ta==-1 || (*it)+1<ta)dp[i+1][0][k]=(*it)+1;
					if(tb==-1 || (*it)+1<tb)dp[i+1][1][k]=(*it)+1;
				}
				//cout<<"("<<t1<<" "<<k<<","<<j<<","<<dp[i][k][j]<<")";
			}
		}
		//cout<<endl;
	}
	cout<<ans<<endl;
	return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 19072
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;
#define rep(i,n) for(ll i=0;i<n;i++)
#define all(A) A.begin(),A.end()


void solve(){
    ll N,D,K;
    cin>>N>>D>>K;
    vector<vector<array<ll,2>>> U(2);
    vector<array<ll,2>> P(N);
    rep(i,N){
        cin>>P[i][1]>>P[i][0];
        P[i][1]--;
    }
    sort(all(P));
    rep(i,N)U[P[i][1]].push_back({P[i][0],i});
    rep(i,2)U[i].push_back({ll(1e18),-1});
    vector<ll> DP(N,1);
    ll an=0;
    for(int i=0;i<N;i++){
        an=max(an,DP[i]);
        array<ll,2> memo={P[i][0],N+10};
        auto p=*(upper_bound(all(U[P[i][1]]),memo));
        if(p[1]!=-1)DP[p[1]]=max(DP[p[1]],DP[i]+1);
        memo={P[i][0]+D+K*DP[i],N+10};
        p=*(upper_bound(all(U[1-P[i][1]]),memo));
        if(p[1]!=-1)DP[p[1]]=max(DP[p[1]],DP[i]+1);
    }
    cout<<an<<endl;
}

int main(){
    
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T=1;
    while(T--)
    solve();
}
accuracy: 1
time_ms: 50
memory_kb: 13372
final_rank: 5

code_snippet: #include<bits/stdc++.h>

using namespace std;

int main() {
    long long N, D, K;
    cin >> N >> D >> K;
    vector<long long> P(N), S(N);
    for (int i = 0; i < N; i++) {
        cin >> P[i] >> S[i];
    }
    vector<long long> V[2];
    V[0].push_back(0);
    V[1].push_back(0);
    for (long long i = 0; i < N; i++) {
        P[i]--;
        V[P[i]].push_back(S[i]);
    }
    for (int i = 0; i <= 1; i++) {
        sort(V[i].begin(), V[i].end());
    }
    long long mx = 4000000000000000000;
    long long dp[2][N + 5];
    for (int i = 0; i <= 1; i++) {
        for (long long k = 0; k <= N; k++) {
            dp[i][k] = mx;
        }
    }
    dp[0][0] = 0;
    dp[1][0] = 0;
    for (long long i = 0; i <= N - 1; i++) {
        if (dp[0][i] != mx) {
            long long now = dp[0][i];
            long long pos = lower_bound(V[0].begin(), V[0].end(), now + 1) - V[0].begin();
            if (pos < V[0].size()) {
                dp[0][i + 1] = min(dp[0][i + 1], V[0][pos]);
            }
            long long cost = D + K * i + 1;
            pos = lower_bound(V[1].begin(), V[1].end(), now + cost) - V[1].begin();
            if (pos < V[1].size()) {
                dp[1][i + 1] = min(dp[1][i + 1], V[1][pos]);
            }
        }
        if (dp[1][i] != mx) {
            long long now = dp[1][i];
            long long pos = lower_bound(V[1].begin(), V[1].end(), now + 1) - V[1].begin();
            if (pos < V[1].size()) {
                dp[1][i + 1] = min(dp[1][i + 1], V[1][pos]);
            }
            long long cost = D + K * i + 1;
            pos = lower_bound(V[0].begin(), V[0].end(), now + cost) - V[0].begin();
            if (pos < V[0].size()) {
                dp[0][i + 1] = min(dp[0][i + 1], V[0][pos]);
            }
        }
    }
    int ans = 0;
    for (int i = 0; i <= N; i++) {
        if (dp[0][i] != mx || dp[1][i] != mx) {
            ans = i;
        }
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 11252
final_rank: 8

code_snippet: #line 1 "a.cpp"
#define PROBLEM ""
#line 2 "/home/kuhaku/home/github/algo/lib/template/template.hpp"
#pragma GCC target("sse4.2,avx2,bmi2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = M_PI;
#line 3 "/home/kuhaku/home/github/algo/lib/template/macro.hpp"
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
#line 3 "/home/kuhaku/home/github/algo/lib/template/sonic.hpp"
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }

    constexpr void operator()() const {}
} sonic;
#line 5 "/home/kuhaku/home/github/algo/lib/template/atcoder.hpp"
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) {
        os << (it == v.begin() ? "" : " ") << *it;
    }
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
template <typename T, typename... Args>
auto make_vector(T x, int arg, Args... args) {
    if constexpr (sizeof...(args) == 0) return std::vector<T>(arg, x);
    else return std::vector(arg, make_vector<T>(x, args...));
}
void Yes(bool is_correct = true) {
    std::cout << (is_correct ? "Yes" : "No") << '\n';
}
void No(bool is_not_correct = true) {
    Yes(!is_not_correct);
}
void YES(bool is_correct = true) {
    std::cout << (is_correct ? "YES" : "NO") << '\n';
}
void NO(bool is_not_correct = true) {
    YES(!is_not_correct);
}
void Takahashi(bool is_correct = true) {
    std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n';
}
void Aoki(bool is_not_correct = true) {
    Takahashi(!is_not_correct);
}
#line 3 "a.cpp"

int main(void) {
    int n;
    ll d, k;
    cin >> n >> d >> k;
    vector<ll> s1, s2;
    rep (i, n) {
        int p;
        ll s;
        cin >> p >> s;
        if (p == 1)
            s1.emplace_back(s);
        else
            s2.emplace_back(s);
    }
    sort(all(s1));
    sort(all(s2));

    vector dp(2, vector(n + 1, INF));
    dp[0][0] = 0;
    dp[1][0] = 0;
    rep (i, n) {
        auto it1 = lower_bound(all(s1), dp[0][i]);
        if (it1 != s1.end())
            chmin(dp[0][i + 1], (*it1) + 1);
        auto it2 = lower_bound(all(s2), dp[0][i] + d + k * i);
        if (it2 != s2.end())
            chmin(dp[1][i + 1], (*it2) + 1);
        auto it3 = lower_bound(all(s2), dp[1][i]);
        if (it3 != s2.end())
            chmin(dp[1][i + 1], (*it3) + 1);
        auto it4 = lower_bound(all(s1), dp[1][i] + d + k * i);
        if (it4 != s1.end())
            chmin(dp[0][i + 1], (*it4) + 1);
    }

    int ans = 0;
    rep (i, n + 1) {
        if (dp[0][i] != INF || dp[1][i] != INF)
            ans = i;
    }
    co(ans);

    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 10020
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using Event = pair<long long, int>; // time, which

void chmax(int &a, int b) { if (a < b) a = b; }

int main() {
    long long N, D, K;
    cin >> N >> D >> K;
    vector<vector<long long>> time(2);
    vector<Event> events({Event(0, 0), Event(0, 1)});
    for (int i = 0; i < N; ++i) {
        long long P, S;
        cin >> P >> S;
        --P;
        time[P].push_back(S);
        events.emplace_back(S, P);
    }
    for (int i = 0; i < 2; ++i) sort(time[i].begin(), time[i].end());
    sort(events.begin(), events.end());

    map<Event, int> dp;
    dp[Event(0, 0)] = dp[Event(0, 1)] = 0;
    for (auto e: events) {
        int p = e.second, cur = dp[e];

        // そのままの町で
        auto it = lower_bound(time[p].begin(), time[p].end(), e.first + 1);
        if (it != time[p].end()) chmax(dp[Event(*it, p)], cur + 1);

        // 移動
        long long need = D + K * cur;
        it = lower_bound(time[1-p].begin(), time[1-p].end(), e.first + 1 + need);
        if (it != time[1-p].end()) chmax(dp[Event(*it, 1-p)], cur + 1);
    }
    int res = 0;
    for (auto it: dp) chmax(res, it.second);
    cout << res << endl;
}
accuracy: 1
time_ms: 170
memory_kb: 21136
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll N, D, K, v;
    cin >> N >> D >> K;
    vector<pair<ll,int>> a(N);
    vector<vector<ll>> tb(2);
    for(int i = 0; i < N; i++){
        cin >> a[i].second >> a[i].first;
        tb[--a[i].second].push_back(a[i].first);
    }
    sort(a.begin(), a.end());
    sort(tb[0].begin(), tb[0].end());
    sort(tb[1].begin(), tb[1].end());
    vector<vector<ll>> dp = {vector<ll>(tb[0].size(), 1), vector<ll>(tb[1].size(), 1)};
    int p0 = 0, p1 = 0, idx;
    for(int i = 0; i < N; i++){
        tie(v, idx) = a[i];
        int j = lower_bound(tb[idx].begin(), tb[idx].end(), v) - tb[idx].begin();
        if(j + 1 < tb[idx].size())dp[idx][j + 1] = max(dp[idx][j + 1], dp[idx][j] + 1);
        if(idx == 0){
            for(ll k = dp[idx][j]; k > p0; k--){
                ll v2 = v + 1 + D + K * k;
                int t = lower_bound(tb[idx ^ 1].begin(), tb[idx ^ 1].end(), v2) - tb[idx ^ 1].begin();
                if(t < tb[idx ^ 1].size()){
                    dp[idx ^ 1][t] = max(dp[idx ^ 1][t], k + 1);
                }
            }
            p0 = max(p0, int(dp[idx][j]));
        }else{
            for(ll k = dp[idx][j]; k > p1; k--){
                ll v2 = v + 1 + D + K * k;
                int t = lower_bound(tb[idx ^ 1].begin(), tb[idx ^ 1].end(), v2) - tb[idx ^ 1].begin();
                if(t < tb[idx ^ 1].size()){
                    dp[idx ^ 1][t] = max(dp[idx ^ 1][t], k + 1);
                }
            }
            p1 = max(p1, int(dp[idx][j]));
        }
    }
    ll ans = 0;
    if(dp[0].size() >= 1)ans = max(ans, dp[0].back());
    if(dp[1].size() >= 1)ans = max(ans, dp[1].back());
    cout << ans << '\n';
}
accuracy: 1
time_ms: 50
memory_kb: 11104
final_rank: 3

code_snippet: #include <bits/stdc++.h>
// #include <atcoder/modint>

#define rep(i, x) for (ll i = 0; i < x; i++)
#define rep2(i, x) for (ll i = 1; i <= x; i++)
#define rep3(i, x, y) for (ll i = x; i < y; i++)
#define REP(i, x) for (ll i = x - 1; i >= 0; i--)
#define REP2(i, x) for (ll i = x; i >= 1; i--)
#define mpa make_pair
#define mpt make_tuple
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define puts(x) cout << (x) << "\n"
using ll = long long;
using ld = long double;
using namespace std;
// using namespace atcoder;

const ll INF = 1000000000000000000;
const int intINF = 1000000000;
const ll mod = 1000000007;
const ll MOD = 998244353;
const ld pi = acos(-1);
// const ld EPS = 1e-9;
typedef string::const_iterator State;
class ParseError
{
};

template <typename T>
bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b; // aをbで更新
        return true;
    }
    return false;
}
template <typename T>
bool chmin(T &a, const T &b)
{
    if (a > b)
    {
        a = b; // aをbで更新
        return true;
    }
    return false;
}

bool isprime(ll p)
{
    if (p == 1)
        return false;
    for (ll i = 2; i * i <= p; i++)
    {
        if (p % i == 0)
            return false;
    }
    return true;
}
//エラトステネスの篩
vector<bool> isprime_format(ll n)
{
    vector<bool> P(n + 1, 1);
    P[0] = P[1] = 1;
    for (ll i = 2; i * i <= n; i++)
    {
        if (!P[i])
            continue;
        for (int j = i + i; j <= n; j += i)
            P[j] = false;
    }
    return P;
}
vector<ll> prime_format(ll n)
{
    vector<bool> P = isprime_format(n);
    vector<ll> ans;
    for (int i = 2; i <= n; i++)
    {
        if (P[i])
            ans.push_back(i);
    }
    return ans;
}
ll extGCD(ll a, ll b, ll &x, ll &y)
{
    // ax + by = cが整数解をもつための必要十分条件は c が gcd(a,b) で割り切れること。
    //  返り値: a と b の最大公約数
    //  ax + by = gcd(a, b) を満たす (x, y) が格納される
    // main関数内に extGCD(a, b, x, y); でx, yに解が格納
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    ll d = extGCD(b, a % b, y, x);
    y -= a / b * x;
    return d;
}
ll keta(ll n)
{
    ll res = 0;
    while (n >= 1)
    {
        // res++;
        res += n % 10;

        n /= 10;
    }
    return res;
}
ll modpow(ll x, ll y, ll m)
{
    ll res = 1;
    while (y)
    {
        if (y % 2)
        {
            res *= x;
            res %= m;
        }
        x = x * x % m;
        y /= 2;
    }
    return res;
}

unsigned int xorshift()
{
    // xorshift　from 「ビット演算 (bit 演算) の使い方を総特集！ 」
    // 1~6まで出したいときは
    // xorshift() % 6 + 1
    static unsigned int tx = 123456789, ty = 362436069, tz = 521288629, tw = 88675123;
    unsigned int tt = (tx ^ (tx << 11));
    tx = ty;
    ty = tz;
    tz = tw;
    return (tw = (tw ^ (tw >> 19)) ^ (tt ^ (tt >> 8)));
}
uint64_t seed = 123456789;
uint64_t xorshift64()
{
    seed ^= seed << 13;
    seed ^= seed >> 17;
    seed ^= seed << 7;
    return seed;
}
int rand_int(int l, int r)
{
    return l + int(xorshift64() % (r - l));
}
double randouble()
{
    return double(xorshift64()) / double(uint64_t(-1));
}

typedef pair<ll, ll> P;
typedef pair<ll, P> pp;
//左上右下
ll dx[4] = {0, -1, 0, 1}, dy[4] = {-1, 0, 1, 0};
ll ndx[4] = {1, -1, -1, 1}, ndy[4] = {1, 1, -1, -1};
char ds[4] = {'l', 'u', 'r', 'd'};
char dl[4] = {'L', 'U', 'R', 'D'};

vector<ll> spf;
void smallest_prime_factors(ll n)
{
    spf.resize(n + 1);
    spf[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        if (!spf[i])
        {
            for (int j = i; j < n; j += i)
            {
                spf[j] = i;
            }
        }
    }
}
std::map<int, int> high_speed_prime_factor(int n)
{
    std::map<int, int> res;
    while (n != 1)
    {
        res[spf[n]]++;
        n /= spf[n];
    }
    return res;
}

////////////////////////////////struct

struct Comb
{
    // https://atcoder.jp/contests/abc156/submissions/33741990

    ll nCrMAX;
    ll m;
    vector<ll> fac, finv, inv; // n!、1/n!、1/n

    Comb(ll kMOD, ll kMAX = 612345)
    {
        nCrMAX = kMAX;
        m = kMOD;
        fac.resize(nCrMAX);
        finv.resize(nCrMAX);
        inv.resize(nCrMAX);

        fac[0] = fac[1] = 1;
        finv[0] = finv[1] = 1;
        inv[1] = 1;
        for (int i = 2; i < nCrMAX; i++)
        {
            fac[i] = fac[i - 1] * i % m;
            inv[i] = m - inv[m % i] * (m / i) % m;
            finv[i] = finv[i - 1] * inv[i] % m;
        }
    }

    ll nCr(ll n, ll k)
    {
        if (k < nCrMAX)
        {
            ll res = 1;
            for (int i = n - k + 1; i <= n; i++)
            {
                res *= i;
                res %= m;
            }
            res = res * finv[k] % m;
            return res;
        }
        else
        {
            if (n < k)
                return 0;
            if (n < 0 || k < 0)
                return 0;
            return fac[n] * (finv[k] * finv[n - k] % m) % m;
        }
    }

    ll nCr1(ll n, ll k)
    {
        if (n < k)
            return 0;
        if (n < 0 || k < 0)
            return 0;
        return fac[n] * (finv[k] * finv[n - k] % m) % m;
    }

    //(nが大きくて)kが小さい時
    // nCrMAXはk+2まででOK
    ll nCr2(ll n, ll k)
    {
        ll res = 1;
        for (int i = n - k + 1; i <= n; i++)
        {
            res *= i;
            res %= m;
        }
        res = res * finv[k] % m;
        return res;
    }
};

struct status
{
    ll v;
    ll p;

    // bool operator<(const status& rhs) const { return c < rhs.c; };
    // bool operator>(const status& rhs) const { return c > rhs.c; };
    bool operator<(const status &rhs) const { return v < rhs.v; };
    bool operator>(const status &rhs) const { return v > rhs.v; };
};
void yes(bool a) { cout << (a ? "yes" : "no") << endl; }
void YES(bool a) { cout << (a ? "YES" : "NO") << endl; }
void Yes(bool a) { cout << (a ? "Yes" : "No") << endl; }
void Possible(bool a) { cout << (a ? "Possible" : "Impossible") << endl; }
// struct edge {
//	ll to; ll cost;
// };

struct Point
{
    ld x, y;
    Point operator+(const Point &p) const noexcept { return {x + p.x, y + p.y}; }
    Point operator-(const Point &p) const noexcept { return {x - p.x, y - p.y}; }
    Point operator*(const ld k) const noexcept { return {x * k, y * k}; }
    Point operator/(const ld k) const noexcept { return {x / k, y / k}; }
    Point &operator+=(const Point &p) noexcept
    {
        x += p.x;
        y += p.y;
        return *this;
    }
    Point &operator-=(const Point &p) noexcept
    {
        x -= p.x;
        y -= p.y;
        return *this;
    }
    bool operator<(const Point &p) const noexcept { return (x != p.x ? x < p.x : y < p.y); }

    ld abs() const noexcept { return sqrt(x * x + y * y); }
    ld norm() const noexcept { return x * x + y * y; }
};

// using mint = modint998244353;

struct edge
{
    ll to, cost;
};

int main()
{
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    // cout << fixed << setprecision(15);
    // priority_queue<ll, vector<ll>, greater<ll>> que;
    // priority_queue<P, vector<P>, greater<P>> que;
    // priority_queue<status, vector<status>, greater<status>> que;

    ll n, d, k;
    cin >> n >> d >> k;
    vector<ll> C(n), T(n), sT(n + 1);
    rep(i, n)
    {
        cin >> C[i] >> T[i];
        C[i]--;
        sT[i] = T[i]; // sort用
    }
    sT[n] = 0;
    sort(all(sT));
    T.erase(unique(all(sT)), sT.end());
    // 時間 t があった時、find(all(sT), t) - sT.begin(); で圧縮座標が分かる。
    // 時間 t があった時、z[t] で圧縮座標が分かる。
    map<ll, ll> z;
    rep(i, (int)sT.size())
    {
        z[sT[i]] = i;
    }
    vector<vector<bool>> Event(2, vector<bool>(n + 1));
    rep(i, n)
    {
        Event[C[i]][z[T[i]]] = true;
    }

    ll ans = 0;
    vector<vector<ll>> dp(2, vector<ll>(n + 1)); // dp[i][j]...街iに時間j(圧縮時間)の時にいるまでに行けるEventの数
    vector<vector<ll>> count(2, vector<ll>(n + 1, INF)); // count[i][k]...k個のイベントに参加した後に町iにいるような最小の時間
    count[0][0] = 0;
    count[1][0] = 0;
    rep2(j, n)
    {
        rep(i, 2)
        {
            ll ok = 0, ng = n + 1;
            while ((ng - ok) > 1)
            {
                ll mid = (ok + ng) / 2; //mid個のEvent
                if (count[1 - i][mid] <= sT[j] - (d + k * mid))
                {
                    ok = mid;
                }
                else
                {
                    ng = mid;
                }
            }

            bool is_Event = Event[i][j];
            dp[i][j] = max(dp[i][j - 1], ok) + is_Event;
            chmax(ans, dp[i][j]);

            chmin(count[i][dp[i][j]], sT[j] + 1);
            chmin(count[1-i][dp[i][j]], sT[j] + d + k * dp[i][j] + 1);
          //cout<<count[1-i][4] << ' ' << dp[i][j-1]<<' '<<ok<<endl;
          //cout<<i<<' '<<j<<' '<<dp[i][j]<<endl;
          //cout<<count[i][dp[i][j]]<<endl;
        }
    }

    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 28120
final_rank: 12

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int dx[]={1,0,0,-1},dy[]={0,1,-1,0};
int main(){
	static int n,p[200000];
	static ll d,k,s[200000];
	cin>>n>>d>>k;
	for(int i=0;i<n;i++)
		cin>>p[i]>>s[i];
	static pair<ll,int>sp[200000];
	for(int i=0;i<n;i++)
		sp[i]={s[i],p[i]};
	sort(sp,sp+n);
	for(int i=0;i<n;i++)
		tie(s[i],p[i])=sp[i];
	vector<int>idx[2];
	for(int i=0;i<n;i++)
		idx[--p[i]].push_back(i);
	static int dp[200000],ans=0;
	for(int i=0;i<n;i++){
		int ok=-1,ng=idx[p[i]].size();
		while(abs(ok-ng)>1){
			int mid=(ok+ng)/2;
			if(s[idx[p[i]][mid]]+1<=s[i])
				ok=mid;
			else
				ng=mid;
		}
		dp[i]=max(dp[i],(ok==-1?0:dp[idx[p[i]][ok]]));
		ok=-1,ng=idx[!p[i]].size();
		while(abs(ok-ng)>1){
			int mid=(ok+ng)/2;
			if(s[idx[!p[i]][mid]]+1+d+k*dp[idx[!p[i]][mid]]<=s[i])
				ok=mid;
			else
				ng=mid;
		}
		dp[i]=max(dp[i],(ok==-1?0:dp[idx[!p[i]][ok]]));
		dp[i]++;
		ans=max(ans,dp[i]);
	}
	cout<<ans<<endl;
}
accuracy: 1
time_ms: 110
memory_kb: 10476
final_rank: 7

code_snippet: #include <iostream>
#include <map>
#include <vector>
#include <algorithm>

using namespace std;

using Int = int_fast64_t;

int main()
{
	int N; cin >> N;
	Int D, K; cin >> D >> K;
	vector<pair<Int, int>> SP(N); for (auto& [S, P] : SP) {cin >> P >> S; --P;}
	sort(SP.begin(), SP.end());
	vector<vector<int>> dp(N, vector<int>(2, 0));
	vector<map<Int, int>> S(2);
	auto [S0, P0] = SP[0];
	dp[0][P0] = 1;
	auto t = S0 + 1 + D + K;
	S[1 - P0][t] = 1;
	for (int i = 1; i < N; ++i) {
		auto [Si, Pi] = SP[i];
		for (int P = 0; P < 2; ++P) {
			dp[i][P] = dp[i - 1][P];
			while (!S[P].empty()) {
				auto [t, n] = *S[P].begin();
				if (t > Si) break;
				dp[i][P] = max(dp[i][P], n);
				S[P].erase(S[P].begin());
			}
		}
		++dp[i][Pi];
		auto t = Si + 1 + D + K * dp[i][Pi];
		S[1 - Pi][t] = max(S[1 - Pi][t], dp[i][Pi]);
	}
	cout << max(dp.back()[0], dp.back()[1]) << endl;
	return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 29608
final_rank: 10

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;

int main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int n; cin >> n;
	ll D,K; cin >> D >> K;
	vector<vector<ll>> g(2);
	for(int i=0;i<n;i++){
		int p; cin >> p;
		ll s; cin >> s;
		g[p-1].push_back(s);
	}
	sort(g[0].begin(), g[0].end());
	sort(g[1].begin(), g[1].end());
	vector<vector<ll>> dp(2,vector<ll>(n+1,1e18));
	dp[0][0]=dp[1][0]=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<2;j++){
			{
				int sz=g[j].end()-lower_bound(g[j].begin(), g[j].end(),dp[j][i-1]);
				if(sz>=1){
					dp[j][i]=min(dp[j][i],g[j][(int)(g[j].size())-sz]+1);
				}
			}
			{
				int sz=g[j].end()-lower_bound(g[j].begin(), g[j].end(),dp[j^1][i-1]+D+(i-1)*K);
				if(sz>=1){
					dp[j][i]=min(dp[j][i],g[j][(int)(g[j].size())-sz]+1);
				}
			}
		}
	}
	int res=0;
	for(int i=0;i<2;i++){
		for(int j=0;j<=n;j++){
			if(dp[i][j]!=1e18)res=max(res,j);
		}
	}
	cout << res << "\n";
}
accuracy: 1
time_ms: 50
memory_kb: 10012
final_rank: 1

code_snippet: #include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <queue>
#include <string>
#include <random>
#include <array>
#include <climits>
#include <map>
#include <cassert>
#include <stack>
#include <iomanip>
#include <cfloat>



int main() {
	int n; long long int d, k; std::cin >> n >> d >> k;
	std::vector<std::pair<int, long long int>> all_events(n);
	for (auto& [p, s] : all_events) {
		std::cin >> p >> s; --p;
	}
	std::sort(all_events.begin(), all_events.end(), [](const auto a, const auto b) {return a.second < b.second; });
	std::vector<std::vector<long long int>> events(2);
	for (const auto [p, s] : all_events) {
		events[p].push_back(s);
	}
	std::vector<std::vector<int>> max_event{std::vector<int>(events[0].size(), 1), std::vector<int>(events[1].size(), 1)};
	for (auto i = 0; i < n; ++i) {
		const auto [p, s] = all_events[i];
		const auto pos = std::distance(events[p].begin(), std::lower_bound(events[p].begin(), events[p].end(), s));
		const auto max = max_event[p][pos];
		const auto succ = std::distance(events[p].begin(), std::upper_bound(events[p].begin(), events[p].end(), s));
		const auto opposite = std::distance(events[1 - p].begin(), std::upper_bound(events[1 - p].begin(), events[1 - p].end(), s + d + k * max));
		if (succ < max_event[p].size()) {
			max_event[p][succ] = std::max(max_event[p][succ], max + 1);
		}
		if (opposite < max_event[1 - p].size()) {
			max_event[1 - p][opposite] = std::max(max_event[1 - p][opposite], max + 1);
		}
	}
	int result{ 0 };
	for (const auto& max : max_event) {
		for (const auto v : max) {
			result = std::max(result, v);
		}
	}
	std::cout << result << '\n';
}
accuracy: 1
time_ms: 100
memory_kb: 9368
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001




#define SIZE 200005


ll N,D,K;
ll P[SIZE],S[SIZE];
ll dp[2][SIZE];
vector<ll> V[2];

int main(){

	scanf("%lld %lld %lld",&N,&D,&K);

	//■ダミー
	V[0].push_back(0);
	V[1].push_back(0);

	for(ll i = 0; i < N; i++){

		scanf("%lld %lld",&P[i],&S[i]);
		P[i]--;

		V[P[i]].push_back(S[i]);
	}
	for(int i = 0; i <= 1; i++){

		sort(V[i].begin(),V[i].end());
	}

	for(int i = 0; i <= 1; i++){
		for(ll k = 0; k <= N; k++){

			//■訪問個数が同じなら、時刻が小さい方が良い
			dp[i][k] = HUGE_NUM; //dp[街][tまでにいくつ街を訪れたか] = 最小時刻(t)
		}
	}

	dp[0][0] = 0;
	dp[1][0] = 0;

	for(ll i = 0; i <= N-1; i++){ //個数
		if(dp[0][i] != HUGE_NUM){

			ll now = dp[0][i]; //現在時刻

			//■街0のまま
			ll pos = lower_bound(V[0].begin(),V[0].end(),now+1)-V[0].begin();
			if(pos < V[0].size()){

				dp[0][i+1] = min(dp[0][i+1],V[0][pos]);
			}
			//■街1へ行く
			ll cost = D+K*i+1;

			pos = lower_bound(V[1].begin(),V[1].end(),now+cost)-V[1].begin();
			if(pos < V[1].size()){

				dp[1][i+1] = min(dp[1][i+1],V[1][pos]);
			}
		}
		if(dp[1][i] != HUGE_NUM){

			ll now = dp[1][i]; //現在時刻

			//■街1のまま
			ll pos = lower_bound(V[1].begin(),V[1].end(),now+1)-V[1].begin();
			if(pos < V[1].size()){

				dp[1][i+1] = min(dp[1][i+1],V[1][pos]);
			}
			//■街0へ行く
			ll cost = D+K*i+1;

			pos = lower_bound(V[0].begin(),V[0].end(),now+cost)-V[0].begin();
			if(pos < V[0].size()){

				dp[0][i+1] = min(dp[0][i+1],V[0][pos]);
			}
		}
	}

	int ans = 0;
	for(int i = 0; i <= N; i++){
		if(dp[0][i] != HUGE_NUM || dp[1][i] != HUGE_NUM){

			ans = i;
		}
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 11196
final_rank: 4