Submission #1136075

#TimeUsernameProblemLanguageResultExecution timeMemory
1136075mychecksedadMizuyokan 2 (JOI23_mizuyokan2)C++20
0 / 100
4097 ms120288 KiB
/* Author : Mychecksdead  */
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define MOD (1000000000+7)
#define MOD1 (998244353)
#define pb push_back
#define all(x) x.begin(), x.end()
#define en cout << '\n'
#define ff first
#define ss second
#define pii pair<int,int>
#define vi vector<int>
const int N = 1e6+100, M = 1e5+10, K = 31, MX = 200;


int n, ANS[N];
ll a[N], pref[N];

vector<array<int, 2>> solv(int A, int B, vector<array<int, 2>> &dp){
  // vector<array<int, 2>> dp(B - A + 2);
  dp[0][0] = dp[0][1] = -MOD;
  dp[1][0] = 1;
  dp[1][1] = -MOD;
  for(int j = A + 1; j <= B; ++j){
      // dp[j][1] = dp[j - 1][1];
    int l = A, r = j - 1, go = j;
    while(l <= r){
      int m = l + r>>1;
      if(pref[j - 1] - pref[m - 1] > a[j]){
        go = m;
        l = m + 1;
      }else r = m - 1;
    }
    dp[j - (A - 1)][0] = dp[j - (A - 1)][1] = 1;
    if(go < j){
      for(int l = go; l >= max(A, go - K); --l){
        if(l == A || pref[j - 1] - pref[l - 1] > a[l - 1]){
          dp[j - (A - 1)][0] = max(dp[j - (A - 1)][0], dp[l - 1 - (A - 1)][0] + 2);
        }
      }
    }
    for(int l = j - 1; l >= max(A, (j-K)); --l){
      if(pref[j] - pref[l] > a[l]){
        dp[j - (A - 1)][1] = max(dp[j - (A - 1)][1], dp[l - (A - 1)][0] + 1);
      }
    }
  }
  return dp;
}

vector<array<int, 2>> solv_rev(int A, int B, vector<array<int, 2>> &dp){
  // vector<array<int, 2>> dp(B - A + 2);
  reverse(a+A, a+B+1);
  pref[A] = pref[A - 1] + a[A];
  for(int j = A + 1; j <= B; ++j) pref[j] = pref[j - 1] + a[j];
  dp[0][0] = dp[0][1] = -MOD;
  dp[1][0] = 1;
  dp[1][1] = -MOD;
  for(int j = A + 1; j <= B; ++j){
      // dp[j][1] = dp[j - 1][1];
    int l = A, r = j - 1, go = j;
    while(l <= r){
      int m = l + r>>1;
      if(pref[j - 1] - pref[m - 1] > a[j]){
        go = m;
        l = m + 1;
      }else r = m - 1;
    }
    dp[j - (A - 1)][0] = dp[j - (A - 1)][1] = 1;
    if(go < j){
      for(int l = go; l >= max(A, go - K); --l){
        if(l == A || pref[j - 1] - pref[l - 1] > a[l - 1]){
          dp[j - (A - 1)][0] = max(dp[j - (A - 1)][0], dp[l - 1 - (A - 1)][0] + 2);
        }
      }
    }
    for(int l = j - 1; l >= max(A, (j-K)); --l){
      if(pref[j] - pref[l] > a[l]){
        dp[j - (A - 1)][1] = max(dp[j - (A - 1)][1], dp[l - (A - 1)][0] + 1);
      }
    }
  }
  reverse(a+A, a+B+1);
  pref[A] = pref[A - 1] + a[A];
  for(int j = A + 1; j <= B; ++j) pref[j] = pref[j - 1] + a[j];
  return dp;
}

vector<array<int, 2>> dpL[K + 5];
vector<array<int, 2>> dpR[K + 5];

void dfs(int l, int r, vector<array<int, 3>> &Q){
  vector<array<int, 3>> L, R, CUR;
  int m = l+r>>1;
  for(auto [x, y, idx]: Q){
    if(y <= m) L.pb({x, y, idx});
    else if(x >= m + 1) R.pb({x, y, idx});
    else CUR.pb({x, y, idx});
  }
  if(CUR.size()){
    if(l == r){
      for(auto [x, y, idx]: CUR){
        ANS[idx] = 1;
      }
      return;
    }
    // vector<vector<array<int, 2>>> dpL;
    int c = 0;
    for(int j = m; j >= max(l, m - K); --j){
      ++c;
      solv_rev(l, j, dpL[c - 1]);
    }
    c = 0;
    for(int j = m + 1; j <= min(r, m + 1 + K); ++j){
      ++c;
      solv(j, r, dpR[c - 1]);
    }
    vector<array<int, 2>> go_right(r - m + 2); solv(m, r, go_right);
    vector<array<int, 2>> go_left(m + 1 - l + 2); solv_rev(l, m + 1, go_left);
    for(auto [x, y, idx]: CUR){
      int ans = 1;
      for(int left = m; left >= max(x, m - K + 1); --left){
        for(int right = m + 1; right <= min(y, m + K); ++right){
          bool aight = true;
          if(!(left == x || pref[right] - pref[left - 1] > a[left - 1])) aight = false;
          if(!(right == y || pref[right] - pref[left - 1] > a[right + 1])) aight = false;
          if(aight){
            int cost = 1 + (left == x ? 0 : max(dpL[m-(left-1)][(left-1)-(x)+1][0], dpL[m-(left-1)][(left-1)-(x)+1][1])) 
              + (right == y ? 0 : max(dpR[(right+1)-(m+1)][(y)-(right+1)+1][0], dpR[(right+1)-(m+1)][(y)-(right+1)+1][1]));
            ans = max(ans, cost);
          }
        }
      }
      ans = max({ans,
        max(go_right[y - m + 1][0], go_right[y - m + 1][1]) + max(dpL[0][m - x + 1][0], dpL[0][m - x + 1][1]) - 1, 
        max(go_left[m + 1 - x + 1][0], go_left[m + 1 - x + 1][1]) + max(dpR[0][y - (m + 1) + 1][0], dpR[0][y - (m + 1) + 1][1]) - 1, 
      });
      ANS[idx] = ans;
    }
  }


  if(l == r) return;
  dfs(l, m, L);
  dfs(m+1, r, R);
}

void solve(){
  cin >> n;
  for(int i = 1; i <= n; ++i){
    cin >> a[i];
  }
  for(int i = 0; i < K+5; ++i) dpL[i].resize(200005);
  for(int i = 0; i < K+5; ++i) dpR[i].resize(200005);
  pref[0] = 0;
  for(int i = 1; i <= n; ++i){
    pref[i] = pref[i - 1] + a[i];
  }
  vector<array<int, 3>> Q;
  int q; cin >> q;
  for(int i = 0; i < q; ++i){
    int x, y, A, B; cin >> x >> y >> A >> B;
    Q.pb({A+1, B, i});
    // ++A;
    // a[x] = y;
    // pref[0] = 0;
    // for(int j = 1; j <= n; ++j){
    //   pref[j] = pref[j - 1] + a[j];
    // }
    // vector<array<int, 2>> dpp = solv(A, B);
    // cout << max(dpp[B-A+1][0], dpp[B-A+1][1]) << '\n';
  }
  dfs(1, n, Q);


  for(int i = 1; i <= q; ++i){
    cout << ANS[i-1] << '\n';
  }
}


int main(){
  cin.tie(0); ios::sync_with_stdio(0);
  int tt = 1, aa;
  // freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
  while(tt--){
    solve();
    en;
  }
  cerr<<"time taken : "<<(float)clock()/CLOCKS_PER_SEC<<" seconds\n";
  return 0;
} 
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...