답안 #938680

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
938680 2024-03-05T12:18:38 Z danikoynov Two Dishes (JOI19_dishes) C++14
3 / 100
472 ms 96156 KB
#include <bits/stdc++.h>
#define endl '\n'

using namespace std;
typedef long long ll;

void speed()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
}

const int maxn = 1e6 + 10;

int n, m;
ll a[maxn], s[maxn], p[maxn];
ll b[maxn], t[maxn], q[maxn];
ll pref[2][maxn];

void input()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i ++)
        cin >> a[i] >> s[i] >> p[i];
    for (int i = 1; i <= m; i ++)
        cin >> b[i] >> t[i] >> q[i];
}

void prefix_sums()
{
    for (int i = 1; i <= n; i ++)
    {
        pref[0][i] = pref[0][i - 1] + a[i];
    }
    for (int i = 1; i <= m; i ++)
    {
        pref[1][i] = pref[1][i - 1] + b[i];
    }
}

ll dp[maxn], temp[maxn];
vector < pair < int, ll > > upd[maxn];
int X[maxn], Y[maxn];
const ll inf = 1e18;

ll tree[4 * maxn];
pair < ll, ll > lazy[4 * maxn]; /// first is addition; second is set
pair < int, int > tag[4 * maxn];

void push_lazy(int root, int left, int right)
{

        if (tag[root].second == 1)
        {
            tree[root] = lazy[root].second;
        }
        if (tag[root].first == 1)
            tree[root] += lazy[root].first;

        if (left != right)
        {
            if (tag[root].second == 1)
            {
                lazy[root * 2] = {0, lazy[root].second};
                lazy[root * 2 + 1] = {0, lazy[root].second};
                tag[root * 2] = {0, 1};
                tag[root * 2 + 1] = {0, 1};
            }
            if (tag[root].first == 1)
            {
                lazy[root * 2].first += lazy[root].first;
                lazy[root * 2 + 1].first += lazy[root].first;
                tag[root * 2].first = 1;
                tag[root * 2 + 1].first = 1;
            }
        }

        lazy[root] = {0, 0};
        tag[root] = {0, 0};

}

void build(int root, int left, int right)
{
    if (left == right)
    {
        tree[root] = dp[left];
        return;
    }

    int mid = (left + right) / 2;
    build(root * 2, left, mid);
    build(root * 2 + 1, mid + 1, right);

    tree[root] = min(tree[root * 2], tree[root * 2 + 1]);
}
ll query(int root, int left, int right, int pivot)
{
    push_lazy(root, left, right);
    if (left == right)
        return tree[root];

    int mid = (left + right) / 2;
    if (pivot <= mid)
        return query(root * 2, left, mid, pivot);
    else
        return query(root * 2 + 1, mid + 1, right, pivot);
}
void range_add(int root, int left, int right, int qleft, int qright, ll val)
{
    push_lazy(root, left, right);
    if (left > qright || right < qleft)
        return;

    if (left >= qleft && right <= qright)
    {
        lazy[root] = {val, 0};
        tag[root] = {1, 0};
        push_lazy(root, left, right);
        return;
    }

    int mid = (left + right) / 2;
    range_add(root * 2, left, mid, qleft, qright, val);
    range_add(root * 2 + 1, mid + 1, right, qleft, qright, val);

    tree[root] = min(tree[root * 2], tree[root * 2 + 1]);

}

void set_range(int root, int left, int right, int qleft, int qright, ll val)
{
    push_lazy(root, left, right);
    if (left > qright || right < qleft)
        return;

    if (left >= qleft && right <= qright)
    {
        lazy[root] = {0, val};
        tag[root] = {0, 1};
        push_lazy(root, left, right);
        return;
    }

    int mid = (left + right) / 2;
    set_range(root * 2, left, mid, qleft, qright, val);
    set_range(root * 2 + 1, mid + 1, right, qleft, qright, val);

    tree[root] = min(tree[root * 2], tree[root * 2 + 1]);

}

int walk(int root, int left, int right, int qleft, int qright, ll val)
{
    push_lazy(root, left, right);
    if (left > qright || right < qleft || tree[root] >= val)
        return qleft - 1;

    if (left == right)
        return left;

        int mid = (left + right) / 2;
    if (left >= qleft && right <= qright)
    {
        if (tree[root * 2 + 1] < val)
            return walk(root * 2 + 1, mid + 1, right, qleft, qright, val);
        return walk(root * 2, left, mid, qleft, qright, val);
    }


    return max(walk(root * 2, left, mid, qleft, qright, val),
               walk(root * 2 + 1, mid + 1, right, qleft, qright, val));
}

void dynamic()
{
    for (int i = 1; i <= n; i ++)
    {
        ll free_time = s[i] - pref[0][i];
        int lf = 0, rf = m;
        while(lf <= rf)
        {
            int mf = (lf + rf) / 2;
            if (pref[1][mf] <= free_time)
                lf = mf + 1;
            else
                rf = mf - 1;
        }
        X[i] = rf;

        /**while(X[i] <= m && pref[1][X[i]] <= free_time)
            X[i] ++;
        X[i] --;*/



        upd[i - 1].push_back({X[i] + 1, - p[i]});
        ///cout << "point " << i - 1 << " " << X[i] + 1 << " " << -p[i] << endl;


    }

    for (int i = 1; i <= m; i ++)
    {
        ll free_time = t[i] - pref[1][i];
        int lf = 0, rf = n;
        while(lf <= rf)
        {
            int mf = (lf + rf) / 2;
            if (pref[0][mf] <= free_time)
                lf = mf + 1;
            else
                rf = mf - 1;
        }
        Y[i] = rf;

        /**while(Y[i] <= n && pref[0][Y[i]] <= free_time)
            Y[i] ++;
        Y[i] --;*/

        if (Y[i] >= 0)
        {
            upd[Y[i]].push_back({i, q[i]});

            //cout << "point " << Y[i] << " " << i << " " << q[i] << endl;
        }
    }

    for (int j = 0; j <= m; j ++)
        dp[j] = 0;
    for (pair < int, ll > cur : upd[0])
        for (int d = cur.first; d <= m; d ++)
        dp[d] += cur.second;

    for (int i = 1; i <= m; i ++)
        dp[i] = max(dp[i], dp[i - 1]);

    build(1, 0, m);

    for (int i = 1; i <= n; i ++)
    {
        sort(upd[i].begin(), upd[i].end());

    /**cout << "--------------" << endl;
    for (int j = 0; j <= m; j ++)
    {
        cout << dp[j] << " " << query(1, 0, m, j) << endl;
    }*/
        ll sum = 0;
        for (int j = 0; j < upd[i].size(); j ++)
        {
            int cur = upd[i][j].first;
            int nxt = m + 1;
            if (j + 1 < upd[i].size())
                nxt = upd[i][j + 1].first;

            sum += upd[i][j].second;
            if (upd[i][j].first == 0 || i == n)
            {
                range_add(1, 0, m, cur, nxt - 1, sum);
                //for (int d = cur; d < nxt; d ++)
                  //  dp[d] += sum;
            }
            else
            {
                ll bef = query(1, 0, m, upd[i][j].first - 1);
                int last = max(cur - 1, walk(1, 0, m, cur, nxt - 1, bef - sum));
                /**int lf = cur, rf = nxt - 1;
                while(lf <= rf)
                {
                    int mf=  (lf + rf) / 2;
                    if (query(1, 0, m, mf) + sum < bef)
                        lf = mf + 1;
                    else
                        rf = mf - 1;
                }
                last = lf - 1;*/
                /**for (int d = cur; d < nxt; d ++)
                {
                    if (query(1, 0, m, d) + sum < bef)
                        last = d;
                }*/

                set_range(1, 0, m, cur, last, bef);
                range_add(1, 0, m, last + 1, nxt - 1, sum);
                /**for (int d = cur; d <= last; d ++)
                    dp[d] = bef;
                for (int d = last + 1; d < nxt; d ++)
                    dp[d] += sum;*/

            }
        }
        /*for (pair < int, ll > cur : upd[i])
        {
            sum += cur.second;

            ll var = dp[cur.first] + sum;

            //cout << "update point " << cur.first << " " << cur.second << endl;

            for (int d = cur.first; d <= m; d ++)
            {
                temp[d] += cur.second;
            }
        }
        for (int j = 0; j <= m; j ++)
        {
            ///best = max(best, dp[j]);
            dp[j] += temp[j];
        }

        if (i != n)
        {
            for (int j = 1; j <= m; j ++)
                dp[j] = max(dp[j - 1], dp[j]);
        }*/

        /**cout << "state " << i << endl;
        for (int j = 0; j <= m; j ++)
            cout << dp[j] << " ";
        cout << endl;*/
    }

    ll res = 0;
    for (int i = 1; i <= n; i ++)
        res += p[i];

    res = res + query(1, 0, m, m);
    cout << res << endl;




    /**for (int i = 0; i <= n; i ++)
    {
        for (int j = 0; j <= m; j ++)
        {
            if (i > 0)
            {
                dp[i][j] = max(dp[i][j], dp[i - 1][j] + (pref[0][i] + pref[1][j] <= s[i]));
            }
            if (j > 0)
            {
                dp[i][j] = max(dp[i][j], dp[i][j - 1] + (pref[0][i] + pref[1][j] <= t[j]));
            }

            ///cout << "state " << i << "  " << j << " " << dp[i][j] << endl;
        }
    }

    cout << dp[n][m] << endl;*/



}
void solve()
{
    input();
    prefix_sums();
    dynamic();
}

int main()
{
    speed();
    solve();
    return 0;
}
/**
9 12
414814218 278771326 1
142790158 568604393 1
155567225 14012701 1
627555390 1224920860 1
677068511 5243031298 1
580933994 8598159379 1
819258172 1432469030 1
340548310 999347990 1
432162069 4373255579 1
99824657 11080715 1
756309567 9502204999 1
929699364 2343419815 1
376204577 6097684636 1
399553538 2306014840 1
824786328 4994974413 1
536419761 3247725215 1
953903194 10674273733 1
787043482 3936134684 1
105275489 567691865 1
861537554 117255456 1
434345770 2420939138 1

*/

Compilation message

dishes.cpp: In function 'int walk(int, int, int, int, int, ll)':
dishes.cpp:160:5: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
  160 |     if (left == right)
      |     ^~
dishes.cpp:163:9: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
  163 |         int mid = (left + right) / 2;
      |         ^~~
dishes.cpp: In function 'void dynamic()':
dishes.cpp:251:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  251 |         for (int j = 0; j < upd[i].size(); j ++)
      |                         ~~^~~~~~~~~~~~~~~
dishes.cpp:255:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  255 |             if (j + 1 < upd[i].size())
      |                 ~~~~~~^~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 412 ms 93780 KB Output is correct
2 Correct 472 ms 96156 KB Output is correct
3 Correct 188 ms 95100 KB Output is correct
4 Correct 293 ms 90316 KB Output is correct
5 Correct 9 ms 49500 KB Output is correct
6 Correct 375 ms 95880 KB Output is correct
7 Correct 104 ms 75452 KB Output is correct
8 Correct 74 ms 66564 KB Output is correct
9 Correct 191 ms 95416 KB Output is correct
10 Incorrect 426 ms 94944 KB Output isn't correct
11 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 49500 KB Output is correct
2 Correct 8 ms 49500 KB Output is correct
3 Correct 8 ms 49596 KB Output is correct
4 Correct 8 ms 49500 KB Output is correct
5 Correct 9 ms 49500 KB Output is correct
6 Correct 8 ms 49500 KB Output is correct
7 Correct 8 ms 49500 KB Output is correct
8 Correct 8 ms 49500 KB Output is correct
9 Correct 9 ms 49500 KB Output is correct
10 Correct 8 ms 49500 KB Output is correct
11 Correct 8 ms 49500 KB Output is correct
12 Correct 8 ms 49680 KB Output is correct
13 Correct 9 ms 49500 KB Output is correct
14 Correct 9 ms 49500 KB Output is correct
15 Correct 8 ms 49500 KB Output is correct
16 Correct 8 ms 49500 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 49500 KB Output is correct
2 Correct 8 ms 49500 KB Output is correct
3 Correct 8 ms 49596 KB Output is correct
4 Correct 8 ms 49500 KB Output is correct
5 Correct 9 ms 49500 KB Output is correct
6 Correct 8 ms 49500 KB Output is correct
7 Correct 8 ms 49500 KB Output is correct
8 Correct 8 ms 49500 KB Output is correct
9 Correct 9 ms 49500 KB Output is correct
10 Correct 8 ms 49500 KB Output is correct
11 Correct 8 ms 49500 KB Output is correct
12 Correct 8 ms 49680 KB Output is correct
13 Correct 9 ms 49500 KB Output is correct
14 Correct 9 ms 49500 KB Output is correct
15 Correct 8 ms 49500 KB Output is correct
16 Correct 8 ms 49500 KB Output is correct
17 Correct 10 ms 49692 KB Output is correct
18 Correct 11 ms 49756 KB Output is correct
19 Incorrect 13 ms 49756 KB Output isn't correct
20 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 49500 KB Output is correct
2 Correct 8 ms 49500 KB Output is correct
3 Correct 8 ms 49596 KB Output is correct
4 Correct 8 ms 49500 KB Output is correct
5 Correct 9 ms 49500 KB Output is correct
6 Correct 8 ms 49500 KB Output is correct
7 Correct 8 ms 49500 KB Output is correct
8 Correct 8 ms 49500 KB Output is correct
9 Correct 9 ms 49500 KB Output is correct
10 Correct 8 ms 49500 KB Output is correct
11 Correct 8 ms 49500 KB Output is correct
12 Correct 8 ms 49680 KB Output is correct
13 Correct 9 ms 49500 KB Output is correct
14 Correct 9 ms 49500 KB Output is correct
15 Correct 8 ms 49500 KB Output is correct
16 Correct 8 ms 49500 KB Output is correct
17 Correct 10 ms 49692 KB Output is correct
18 Correct 11 ms 49756 KB Output is correct
19 Incorrect 13 ms 49756 KB Output isn't correct
20 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 49500 KB Output is correct
2 Correct 8 ms 49500 KB Output is correct
3 Correct 8 ms 49596 KB Output is correct
4 Correct 8 ms 49500 KB Output is correct
5 Correct 9 ms 49500 KB Output is correct
6 Correct 8 ms 49500 KB Output is correct
7 Correct 8 ms 49500 KB Output is correct
8 Correct 8 ms 49500 KB Output is correct
9 Correct 9 ms 49500 KB Output is correct
10 Correct 8 ms 49500 KB Output is correct
11 Correct 8 ms 49500 KB Output is correct
12 Correct 8 ms 49680 KB Output is correct
13 Correct 9 ms 49500 KB Output is correct
14 Correct 9 ms 49500 KB Output is correct
15 Correct 8 ms 49500 KB Output is correct
16 Correct 8 ms 49500 KB Output is correct
17 Correct 10 ms 49692 KB Output is correct
18 Correct 11 ms 49756 KB Output is correct
19 Incorrect 13 ms 49756 KB Output isn't correct
20 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 49500 KB Output is correct
2 Correct 8 ms 49500 KB Output is correct
3 Correct 8 ms 49596 KB Output is correct
4 Correct 8 ms 49500 KB Output is correct
5 Correct 9 ms 49500 KB Output is correct
6 Correct 8 ms 49500 KB Output is correct
7 Correct 8 ms 49500 KB Output is correct
8 Correct 8 ms 49500 KB Output is correct
9 Correct 9 ms 49500 KB Output is correct
10 Correct 8 ms 49500 KB Output is correct
11 Correct 8 ms 49500 KB Output is correct
12 Correct 8 ms 49680 KB Output is correct
13 Correct 9 ms 49500 KB Output is correct
14 Correct 9 ms 49500 KB Output is correct
15 Correct 8 ms 49500 KB Output is correct
16 Correct 8 ms 49500 KB Output is correct
17 Correct 10 ms 49692 KB Output is correct
18 Correct 11 ms 49756 KB Output is correct
19 Incorrect 13 ms 49756 KB Output isn't correct
20 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 412 ms 93780 KB Output is correct
2 Correct 472 ms 96156 KB Output is correct
3 Correct 188 ms 95100 KB Output is correct
4 Correct 293 ms 90316 KB Output is correct
5 Correct 9 ms 49500 KB Output is correct
6 Correct 375 ms 95880 KB Output is correct
7 Correct 104 ms 75452 KB Output is correct
8 Correct 74 ms 66564 KB Output is correct
9 Correct 191 ms 95416 KB Output is correct
10 Incorrect 426 ms 94944 KB Output isn't correct
11 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 412 ms 93780 KB Output is correct
2 Correct 472 ms 96156 KB Output is correct
3 Correct 188 ms 95100 KB Output is correct
4 Correct 293 ms 90316 KB Output is correct
5 Correct 9 ms 49500 KB Output is correct
6 Correct 375 ms 95880 KB Output is correct
7 Correct 104 ms 75452 KB Output is correct
8 Correct 74 ms 66564 KB Output is correct
9 Correct 191 ms 95416 KB Output is correct
10 Incorrect 426 ms 94944 KB Output isn't correct
11 Halted 0 ms 0 KB -