Блог пользователя shinchankosen

Автор shinchankosen, история, 5 дней назад, По-английски

Problem D in EPIC Institute of Technology Round Summer 2024

I'm not good at English, and this is my first post. I usually post here in Japanese. Nice to meet you.

These are my solution.

$$$O(N^2)$$$

Tutorial says DP, and most Accepted programs are DP, too.

But, my program is greedy. Is greedy the correct way to solve it?

C++ 109 ms

$$$O(N \log N)$$$

use Lazy Segment Tree. If the above greedy is correct, then lazysegtree can be used.

C++ 62 ms

  • Проголосовать: нравится
  • +26
  • Проголосовать: не нравится

»
5 дней назад, # |
  Проголосовать: нравится +8 Проголосовать: не нравится

hopefully

»
5 дней назад, # |
  Проголосовать: нравится +8 Проголосовать: не нравится

I tried solving this using greedy using the logic of by letting bob eat the first cake that if he eats entirely then alice wont be able to eat it but it fails so i thought greedy wont work. can you explain your logic plz orz

»
5 дней назад, # |
Rev. 2   Проголосовать: нравится +24 Проголосовать: не нравится

You can rewrite the problem using the following operations:

min_convolution(f(x), g(x)) where both functions are convex

cut(f(x), c) which returns a function that is f(x) in case f(x) <= c and removes that x from the domain if f(x) > c.

Those are the base for slope trick solutions, so you can code the greedy using slope trick ideas as in https://codeforces.com/contest/1987/submission/268375661

So the answer is yes.

»
5 дней назад, # |
  Проголосовать: нравится -19 Проголосовать: не нравится

Yes it's greedy

»
5 дней назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

The greedy solution to the problem

https://codeforces.com/problemset/problem/1526/C2

also works.

Here is my submission

https://codeforces.com/contest/1987/submission/268369424

Credits go to Everule for pointing out the similarity, after which I upsolved the problem.

The lazy propagation solution seems to be listed in the editorial for C2.

»
5 дней назад, # |
  Проголосовать: нравится +8 Проголосовать: не нравится

Thank you for many comments! My latest solution is 268430825 .

#include <bits/stdc++.h>
using namespace std;
 
void solve() {
    int n;
    cin >> n;
    vector<int> cnt(n + 1, 0);
    for(int i = 0; i < n; i ++) {
        int a; cin >> a;
        cnt[a] ++;
    }
    priority_queue<int> q;
    int sum = 0, valid = 0;
    for(int e : cnt) if(e) {
        valid ++;
        sum += e + 1;
        q.push(e + 1);
        while(sum > valid) {
            sum -= q.top();
            q.pop();
        }
    }
    cout << valid - q.size() << endl;
}
 
int main() {
    int t; cin >> t;
    while(t --) solve();
    return 0;
}