Submission #1077541

# Submission time Handle Problem Language Result Execution time Memory
1077541 2024-08-27T07:57:00 Z bleahbleah Tricks of the Trade (CEOI23_trade) C++17
Compilation error
0 ms 0 KB
#include <bits/stdc++.h>
#define all(x) (x).begin(),(x).end()
using namespace std;
 
using ll = long long;
using ld = long double;
 
#define int ll
#define sz(x) ((int)(x).size())
 
using pii = pair<int,int>;
using tii = tuple<int,int,int>;
 
const int nmax = 25e4 + 5;
 
int K;
 
const ll inf = 1e18;
 
struct KthHeap {
   multiset<int> outside, inside;
   void repair() {
      while(sz(inside) > K) {
         int x = *inside.begin();
         inside.erase(inside.find(x));
         outside.insert(x);
         sum -= x;
      }
      while(sz(inside) < K && sz(outside)) {
         int x = *outside.rbegin();
         outside.erase(outside.find(x));
         inside.insert(x);
         sum += x;
      }
      while(sz(inside) && sz(outside) && *inside.begin() < *outside.rbegin()) {
         int x = *outside.rbegin(), y = *inside.begin();
         outside.erase(outside.find(x));
         inside.erase(inside.find(y));
         outside.emplace(y);
         inside.emplace(x);
         sum += x - y;
      }
      return;
   }
   void erase(int x) {
      if(outside.find(x) != outside.end())
         outside.erase(outside.find(x));
      else if(inside.find(x) != inside.end())
         inside.erase(inside.find(x)), sum -= x;
      else assert(false);
      repair();
   }
   void insert(int x) {
      outside.emplace(x);
      repair();
   }
   ll query() {
      repair();
      if(sz(inside) < K) return -inf;
      return sum;
   }
   void clear() { inside.clear(); outside.clear(); }
   
   private:
      ll sum = 0;
};
 
int bestcut[nmax];
ll dp[nmax];
 
ll spart[nmax];
ll S[nmax];
ll v[nmax];
ll V[nmax];
 
ll S(int l, int r) { return spart[r] - spart[l - 1]; }
 
namespace Divide {
   KthHeap hint;
   
   void divide(int l, int r) {
      if(l + 1 == r) return;
      int optl = bestcut[l], optr = bestcut[r];
      
      int mid = l + r >> 1;
      if(r <= optl) {
         for(int i = mid; i < r; i++) hint.insert(v[i]);
         ll best = hint.query() - S(mid, optl);
         int atr = optl;
         for(int i = optl + 1; i <= optr; i++) {
            hint.insert(v[i]);
            if(hint.query() - S(mid, i) >= best) tie(best, atr) = make_pair(hint.query() - S(mid, i), i);
         }
         bestcut[mid] = atr, dp[mid] = best;
         if(atr - mid + 1 == K) {
            int SA = S(mid, atr), SB = 0;
            for(int i = mid; i <= atr; i++) SB += v[i];
         }
         
         for(int i = optl + 1; i <= optr; i++) hint.erase(v[i]);
         divide(l, mid);
         for(int i = mid; i < r; i++) hint.erase(v[i]);
         for(int i = optl + 1; i <= atr; i++) hint.insert(v[i]);
         divide(mid, r);
         for(int i = optl + 1; i <= atr; i++) hint.erase(v[i]);
      }
      else {
         int border = max(mid - 1, optl);
         for(int i = mid; i <= border; i++) hint.insert(v[i]);
         ll best = hint.query() - S(mid, border), atr = border;
         for(int i = border + 1; i <= optr; i++) {
            hint.insert(v[i]);
            if(hint.query() - S(mid, i) >= best) tie(best, atr) = make_pair(hint.query() - S(mid, i), i);
         }
         
         bestcut[mid] = atr, dp[mid] = best;
         
         for(int i = optr; i > border; i--) hint.erase(v[i]);
         divide(l, mid);
         for(int i = mid; i <= border; i++) hint.erase(v[i]);
         for(int i = r; i <= atr; i++) hint.insert(v[i]);
         divide(mid, r);
         for(int i = r; i <= atr; i++) hint.erase(v[i]);
      }
   }
   
}
 
 
vector<int> solve(int n, bool first = 1) {
   Divide::hint.clear();
   for(int i = 1; i <= n; i++) spart[i] = S[i] + spart[i - 1], dp[i] = -inf, bestcut[i] = 0;
   bestcut[0] = 0;
   bestcut[n - K + 2] = n;
   Divide::divide(0, n - K + 2);
   ll mx = -inf;
   
   vector<int> possible(n + 1);
   
   
   for(int i = 1; i <= n - K + 1; i++) 
      mx = max(mx, dp[i]);
   if(first)
      cout << mx << '\n';
   
   auto cmp = [&](int a, int b) { return (v[a] < v[b] || (v[a] == v[b] && a < b)); };
   set<int, decltype(cmp)> inside(cmp), outside(cmp);
   
   int criteriaIL = n + 1, criteriaIR = -1, criteriaV = inf;
   
   KthHeap forchristsake;
   
   
   for(int i = 1; i <= n; i++) {
      //cerr << i << ' ' << bestcut[i] << ' ' << forchristsake.query() << '\t';
      //for(auto x : forchristsake.inside) cerr << x << ' ';
      //for(auto x : forchristsake.outside) cerr << x << ' ';
      //cerr << '\n';
      
      for(int j = bestcut[i - 1] + 1; j <= bestcut[i]; j++) {
         forchristsake.insert(v[j]);
         inside.insert(j);
         while(sz(inside) > K && [&]() {
           auto it = inside.begin(), it2 = next(it);
            return v[*it] < v[*it2];
         }()) {
            auto t = *inside.begin();
            if(t <= criteriaIR && v[t] >= criteriaV) possible[t] = 1;
            inside.erase(inside.begin());
            outside.insert(t);
         }
         //cerr << '\t' << i << ' ' << j << ' ' << forchristsake.query() << ' ' << S(i, j) << '\n';
         if(forchristsake.query() - S(i, j) == mx) {            
            criteriaIR = bestcut[i];
            criteriaV = v[*inside.begin()];
         }
      }
      if(dp[i] == mx) {
         criteriaIR = bestcut[i];
         criteriaV = v[*inside.begin()];
         //for(auto x : inside) cerr << x << ' ';
         //cerr << '\n';
         //cerr << criteriaIR << ' ' << criteriaV << '\n';
      }
      
      forchristsake.erase(v[i]);
      if(inside.count(i)) {
         if(criteriaIR >= i && v[i] >= criteriaV) possible[i] = 1;
         inside.erase(i); 
      }
      else if(outside.count(i)) outside.erase(i);
      while(sz(inside) < K && sz(outside)) {
         int a = *outside.rbegin();
         outside.erase(a);
         inside.insert(a);
      }
   }
   
   while(!inside.empty()) {
      int t = *inside.begin();
      //cerr << t << ' ' << (t <= criteriaIR && v[t] >= criteriaV) << '\n';
      if(t <= criteriaIR && v[t] >= criteriaV) possible[t] = 1;
      inside.erase(inside.begin());
   }
   for(int i = n; i > 0; i--) spart[i] -= spart[i - 1];
   
   return possible;
}
 
signed main() {
   cin.tie(0) -> sync_with_stdio(0);
   int n;
   cin >> n >> K;
   for(int i = 1; i <= n; i++) {
      cin >> S[i];
   }
   for(int i = 1; i <= n; i++)
      cin >> v[i], V[i] = v[i];
   auto T = solve(n, 1);
   reverse(S + 1, S + n + 1);
   reverse(V + 1, V + n + 1);
   for(int i = 1; i <= n; i++) v[i] = V[i];
   auto T1 = solve(n, 0);
   for(int i = 1; i <= n; i++) cout << (T[i] || T1[n - i + 1]);
   cout << '\n';
    
 
}

Compilation message

trade.cpp:76:18: error: 'll S(ll, ll)' redeclared as different kind of entity
   76 | ll S(int l, int r) { return spart[r] - spart[l - 1]; }
      |                  ^
trade.cpp:72:4: note: previous declaration 'll S [250005]'
   72 | ll S[nmax];
      |    ^
trade.cpp: In function 'void Divide::divide(ll, ll)':
trade.cpp:85:19: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   85 |       int mid = l + r >> 1;
      |                 ~~^~~
trade.cpp:88:46: error: 'S' cannot be used as a function
   88 |          ll best = hint.query() - S(mid, optl);
      |                                              ^
trade.cpp:92:39: error: 'S' cannot be used as a function
   92 |             if(hint.query() - S(mid, i) >= best) tie(best, atr) = make_pair(hint.query() - S(mid, i), i);
      |                                       ^
trade.cpp:92:100: error: 'S' cannot be used as a function
   92 |             if(hint.query() - S(mid, i) >= best) tie(best, atr) = make_pair(hint.query() - S(mid, i), i);
      |                                                                                                    ^
trade.cpp:96:32: error: 'S' cannot be used as a function
   96 |             int SA = S(mid, atr), SB = 0;
      |                                ^
trade.cpp:97:45: error: 'SB' was not declared in this scope; did you mean 'SA'?
   97 |             for(int i = mid; i <= atr; i++) SB += v[i];
      |                                             ^~
      |                                             SA
trade.cpp:96:17: warning: unused variable 'SA' [-Wunused-variable]
   96 |             int SA = S(mid, atr), SB = 0;
      |                 ^~
trade.cpp:110:48: error: 'S' cannot be used as a function
  110 |          ll best = hint.query() - S(mid, border), atr = border;
      |                                                ^
trade.cpp:113:39: error: 'S' cannot be used as a function
  113 |             if(hint.query() - S(mid, i) >= best) tie(best, atr) = make_pair(hint.query() - S(mid, i), i);
      |                                       ^
trade.cpp:113:60: error: 'atr' was not declared in this scope
  113 |             if(hint.query() - S(mid, i) >= best) tie(best, atr) = make_pair(hint.query() - S(mid, i), i);
      |                                                            ^~~
trade.cpp:113:100: error: 'S' cannot be used as a function
  113 |             if(hint.query() - S(mid, i) >= best) tie(best, atr) = make_pair(hint.query() - S(mid, i), i);
      |                                                                                                    ^
trade.cpp:116:25: error: 'atr' was not declared in this scope
  116 |          bestcut[mid] = atr, dp[mid] = best;
      |                         ^~~
trade.cpp: In function 'std::vector<long long int> solve(ll, bool)':
trade.cpp:173:43: error: 'S' cannot be used as a function
  173 |          if(forchristsake.query() - S(i, j) == mx) {
      |                                           ^
trade.cpp:149:8: warning: unused variable 'criteriaIL' [-Wunused-variable]
  149 |    int criteriaIL = n + 1, criteriaIR = -1, criteriaV = inf;
      |        ^~~~~~~~~~