Submission #952479

#TimeUsernameProblemLanguageResultExecution timeMemory
952479nguyennhBigger segments (IZhO19_segments)C++14
37 / 100
262 ms142264 KiB
#include<bits/stdc++.h>
#define el '\n'
using namespace std ;

mt19937 rd(chrono::steady_clock::now().time_since_epoch().count());

const int64_t inf = 1e18;
const int MN = 5e5 + 5;

int a[MN] , n;

namespace sub_trau{
  int x[25] , ans = 0;
  
  void backtrack(int k){
    if (k > n - 1){
      int cur = 0 , sum = 0 , cnt = 0;
      bool check = true;
      for ( int i = 1 ; i <= n; i++ ){
        sum += a[i];
        if (x[i] == 1){
          if (sum < cur){
            check = false;
            break;
          }
          cnt++;
          cur = sum;
          sum = 0;
        }
      }
      if (check) ans = max(ans , cnt);
      return;
    }
    for ( int i = 0 ; i <= 1 ; i++ ){
      x[k] = i;
      backtrack(k + 1);
    }
  }
  
  void solve(){
    x[n] = 1;
    backtrack(1);
    cout << ans;
  }
}

namespace sub3{
  void solve(){
    vector<int64_t> pref(n + 5);
    for ( int i = 1 ; i <= n ; i++ ) pref[i] = pref[i - 1] + a[i];
    vector<vector<int64_t>> dp(n + 5 , vector<int64_t>(n + 5)) , suf(n + 5 , vector<int64_t>(n + 5 , 0));
    dp[1][1] = 1;
    suf[1][1] = 1;
    for ( int i = n ; i >= 1 ; i-- ) suf[1][i] = min(suf[1][i + 1] , suf[1][i]);
    for ( int i = 1 ; i <= n ; i++ ){
      for ( int j = i ; j >= 1 ; j-- ){
        int l = 1 , r = j , pos = -1;
        while (l <= r){
          int mid = l + r >> 1;
          if (pref[j - 1] - pref[mid - 1] <= pref[i] - pref[j - 1]){
            pos = mid;
            r = mid - 1;
          }
          else l = mid + 1;
        } 
        assert(pos != -1);
        if (pos == 1) pos--;
        if (!pos){
          dp[i][j] = max(dp[i][j] , suf[j - 1][pos] + 1);
        }
        else {
          if (suf[j - 1][pos]) dp[i][j] = max(dp[i][j] , suf[j - 1][pos] + 1);
        }
      }
      for ( int j = i ; j >= 0 ; j-- ) suf[i][j] = max(suf[i][j + 1] , dp[i][j]);
    }
    int64_t ans = 0;
    for ( int i = 1 ; i <= n ; i++ ){
      ans = max(ans , dp[n][i]);
    }
    cout << ans;
  }
}

namespace sub_final{
  struct Segtri{
    vector<int64_t> st;
    
    Segtri(int n) : st(4 * n + 5) {
      for ( int i = 1 ; i <= 4 * n ; i++ ) st[i] = inf;
    };
    
    void update(int id , int l , int r , int i , int val){
      if (i < l || i > r) return;
      if (l == r){
        st[id] = val;
        return;
      }
      int mid = l + r >> 1;
      update(id << 1 , l , mid , i , val);
      update(id << 1 | 1 , mid + 1 , r , i , val);
      st[id] = min(st[id << 1] , st[id << 1 | 1]);
    }
    
    int walk(int id , int l , int r , int64_t val){
      if (l == r) return l;
      int mid = l + r >> 1;
      if (st[id << 1] <= val) return walk(id << 1 , l , mid , val);
      return walk(id << 1 | 1 , mid + 1 , r , val);
    }
  };
  
  void solve(){
    vector<int64_t> pref(n + 5) , dp(n + 5);
    reverse(a + 1 , a + n + 1);
    for ( int i = n ; i >= 1 ; i-- ) pref[i] = pref[i + 1] + a[i];
    Segtri it(n + 1);
    it.update(1 , 1 , n + 1 , n + 1 , 0);
    for ( int i = n ; i >= 1 ; i-- ){
      int pos = it.walk(1 , 1 , n + 1 , pref[i]);
      dp[i] = dp[pos] + 1;
//      cout << a[i] << " " << a[pos] << " " << dp[i] << el;
      it.update(1 , 1 , n + 1 , i , 2 * pref[i] - pref[pos]);
    }
    cout << dp[1];
  }
}

int32_t main (){
//  freopen("segments.inp" , "r" , stdin);
//  freopen("segments.out" , "w" , stdout);
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> n;
  for ( int i = 1 ; i <= n ; i++ ) cin >> a[i];
  if (n <= 20){
    sub_trau::solve();
    return 0;
  }
  if (n <= 3000){
    sub3::solve();
    return 0;
  }
  sub_final::solve();
}

Compilation message (stderr)

segments.cpp: In function 'void sub3::solve()':
segments.cpp:59:23: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   59 |           int mid = l + r >> 1;
      |                     ~~^~~
segments.cpp: In member function 'void sub_final::Segtri::update(int, int, int, int, int)':
segments.cpp:99:19: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   99 |       int mid = l + r >> 1;
      |                 ~~^~~
segments.cpp: In member function 'int sub_final::Segtri::walk(int, int, int, int64_t)':
segments.cpp:107:19: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  107 |       int mid = l + r >> 1;
      |                 ~~^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...