Submission #1337689

#TimeUsernameProblemLanguageResultExecution timeMemory
1337689adscodingExhibition (JOI19_ho_t2)C++20
100 / 100
156 ms12552 KiB
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define FOR(i, a, b) for (int i = a, _b = b; i <= _b; ++i)
#define FORD(i, a, b) for (int i = a, _b = b; i >= _b; --i)
#define FORLL(i, a, b) for (ll i = a, _b = b; i <= _b; ++i)
#define FORDLL(i, a, b) for (ll i = a, _b = b; i >= _b; --i)
#define all(x) x.begin(), x.end()
#define uni(x) sort(all(x)), x.erase(unique(all(x)), x.end())
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define dbg(...) debug(#__VA_ARGS__, __VA_ARGS__)

template<typename T>
void __print_one(const char *&s, const T &x)
{
    while (*s == ' ') ++s;
    const char *p = s;
    int bal = 0;
    while (*s)
    {
        if (*s == '(') ++bal;
        else if (*s == ')') --bal;
        else if (*s == ',' && bal == 0) break;
        ++s;
    }
    cerr.write(p, s - p) << " = " << x;
    if (*s == ',')
    {
        ++s;
        cerr << "  ,  ";
    }
}

template<typename... Args>
void debug(const char *s, Args... args)
{
    cerr << "[  ";
    int dummy[] = { 0 , ( __print_one(s, args) , 0 )... };
    (void)dummy;
    cerr << "  ]\n\n";
}

template<class X>
bool maximize(X &a, X b)
{
    if (a < b)
    {
        a = b;
        return true;
    }
    return false;
}

template<class X>
bool minimize(X &a, X b)
{
    if (a > b)
    {
        a = b;
        return true;
    }
    return false;
}

// --------------------------------------------------------------------------------------------

const int maxn = 1e5 + 3;
int n, m, Noi[maxn];
struct Obj
{
    ll S, V;
    bool operator < (const Obj &other) const
    {
        if (V != other.V) return V < other.V;
        return S < other.S;
    }
};
ll F[maxn];
Obj a[maxn];

// --------------------------------------------------------------------------------------------

namespace sub12
{
    int dp[5005][5005];

    void solve()
    {
        FOR(i, 1, n)
        {
            FOR(j, 0, m)
            {
                dp[i][j] = dp[i - 1][j];
            }
            FOR(j, Noi[i], m)
                maximize(dp[i][j], dp[i - 1][j - 1] + 1);

            FOR(j, 1, m)
                maximize(dp[i][j], dp[i][j - 1]);
        }

        cout << dp[n][m];
    }
}

namespace AC
{
    mt19937_64 rd(chrono::steady_clock::now().time_since_epoch().count());
    int rand(int l, int r)
    {
        assert(l <= r);
        return uniform_int_distribution<int> (l, r) (rd);
    }
    struct Node
    {
        Node *left, *right;
        ll val, lz; int pr, sz;
        Node(ll _val = 0)
        {
            left = right = nullptr;
            sz = 1;
            val = _val;
            lz = 0;
            pr = rand(-1e9, 1e9);
        }
    };
    Node *treap;

    int get_sz(Node *treap)
    {
        if (!treap) return 0;
        return treap->sz;
    }

    void push(Node *treap)
    {
        if (!treap) return;
        if (treap->left)
        {
            treap->left->lz += treap->lz;
            treap->left->val += treap->lz;
        }
        if (treap->right)
        {
            treap->right->val += treap->lz;
            treap->right->lz += treap->lz;
        }
        treap->lz = 0;
    }

    void pull(Node *treap)
    {
        if (!treap) return;
        treap->sz = 1;
        if (treap->left) treap->sz += treap->left->sz;
        if (treap->right) treap->sz += treap->right->sz;
    }

    void split(Node *treap, Node *&L, Node *&R, int k)
    {
        if (!treap)
        {
            L = nullptr;
            R = nullptr;
            return;
        }

        push(treap);
        if (get_sz(treap->left) >= k)
        {
            R = treap;
            split(treap->left, L, R->left, k);
        }
        else
        {
            L = treap;
            split(treap->right, L->right, R, k - get_sz(treap->left) - 1);
        }

        pull(treap);
    }

    Node *merge(Node *L, Node *R)
    {
        if (!L) return R;
        if (!R) return L;

        if (L->pr > R->pr)
        {
            push(L);
            L->right = merge(L->right, R);
            pull(L);
            return L;
        }

        push(R);
        R->left = merge(L, R->left);
        pull(R);
        return R;
    }

    int get(Node *treap, int k)
    {
        if (!treap) return 0;
        push(treap);
        if (k <= get_sz(treap->left))
            return get(treap->left, k);
        k -= get_sz(treap->left);
        if (k == 1) return treap->val;
        --k;
        return get(treap->right, k);
    }

    void solve()
    {
        FOR(i, 0, m)
            treap = merge(treap, new Node(0));

        FOR(i, 1, n)
        {
            int pos = Noi[i] + 1;
            Node *A = nullptr, *B = nullptr, *C = nullptr;
            int cur = get(treap, pos - 1);
            split(treap, A, B, pos - 2);

//            dbg(i, pos);
//            dbg(get_sz(A), get_sz(B));
            split(B, B, C, get_sz(B) - 1);
            if (B)
            {
                B->val++;
                B->lz++;
            }
            treap = merge(A, new Node(cur));
            treap = merge(treap, B);

//            FOR(j, 0, m)
//                dbg(j, get(treap, j + 1));
        }

        cout << get(treap, m + 1);
    }
}

void solve()
{
    cin >> n >> m;
    FOR(i, 1, n)
    {
        cin >> a[i].S >> a[i].V;
    }
    FOR(i, 1, m)
    {
        cin >> F[i];
    }
    sort(a + 1, a + n + 1);
    sort(F + 1, F + m + 1);

    FOR(i, 1, n)
    {
        Noi[i] = lower_bound(F + 1, F + m + 1, a[i].S) - F;
    }

    if (n <= 4000 && m <= 4000) sub12 :: solve();
    else AC :: solve();
}

signed main()
{
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    #define TASK "TEST"
    if (fopen(TASK".INP", "r"))
    {
        freopen(TASK".INP", "r", stdin);
        freopen(TASK".OUT", "w", stdout);
    }
    solve();
    return 0;
}

Compilation message (stderr)

joi2019_ho_t2.cpp: In function 'int main()':
joi2019_ho_t2.cpp:280:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  280 |         freopen(TASK".INP", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
joi2019_ho_t2.cpp:281:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  281 |         freopen(TASK".OUT", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...