제출 #1344091

#제출 시각아이디문제언어결과실행 시간메모리
1344091SmuggingSpunSeesaw (JOI22_seesaw)C++20
100 / 100
300 ms79768 KiB
#include<bits/stdc++.h>
#define taskname "A"
using namespace std;
typedef long long ll;
typedef long double ld;
template<class T>void minimize(T& a, T b){
  if(a > b){
    a = b;
  }
}
template<class T>void maximize(T& a, T b){
  if(a < b){
    a = b;
  }
}
const int lim = 2e5 + 5;
int n, a[lim];
ll f[lim];
ld calc(int l, int r){
  return ld(f[r] - f[l - 1]) / (r - l + 1);
}
namespace sub1{
  void solve(){
    ld ans = 1e9;
    for(int mask = 0; mask < (1 << (n - 1)); mask++){
      int l = 1, r = n;
      ld left = 1e9, right = 0;
      for(int bit = 0; bit + 1 < n; bit++){
        ld x = calc(l, r);
        minimize(left, x);
        maximize(right, x);
        if(mask >> bit & 1){
          l++;
        }
        else{
          r--;
        }
      }
      ld x = calc(l, l);
      minimize(ans, max(right, x) - min(left, x));
    }
    cout << setprecision(12) << fixed << ans;
  }
}
namespace sub2{
  const int lim = 102;
  bitset<lim>cur, can[lim];
  bool check(){
    cur = can[n];
    for(int len = n - 1; len > 0; len--){
      cur = (cur | (cur << 1)) & can[len];
    }
    return cur.any();
  }
  void solve(){
    vector<vector<ld>>val(n + 1, vector<ld>(n + 1));
    vector<pair<int, int>>range;
    for(int l = 1; l <= n; l++){
      for(int r = l; r <= n; r++){
        range.push_back(make_pair(l, r));
        val[l][r] = calc(l, r);
      }
    }
    sort(range.begin(), range.end(), [&] (pair<int, int>i, pair<int, int>j){
      return val[i.first][i.second] < val[j.first][j.second];
    });
    for(int len = n; len > 0; len--){
      can[len].reset();
    }
    ld ans = 1e9;
    for(int i = 0, j = 0; i < range.size(); i++){
      auto& [l, r] = range[i];
      can[r - l + 1][l] = true;
      if(check()){
        while(true){
          auto& [jl, jr] = range[j];
          can[jr - jl + 1][jl] = false;
          if(!check()){
            can[jr - jr + 1][jl] = true;
            break;
          }
          j++;
        }
        minimize(ans, val[l][r] - val[range[j].first][range[j].second]);
      }
    }
    cout << setprecision(12) << fixed << ans;
  }
}
namespace sub3{
  void solve(){
    vector<vector<ld>>val(n + 1, vector<ld>(n + 1));
    vector<pair<int, int>>range;
    for(int l = 1; l <= n; l++){
      for(int r = l; r <= n; r++){
        range.push_back(make_pair(l, r));
        val[l][r] = calc(l, r);
      }
    }
    sort(range.begin(), range.end(), [&] (pair<int, int>i, pair<int, int>j){
      return val[i.first][i.second] < val[j.first][j.second];
    });
    vector<int>cnt(n, 0);
    ld ans = 1e9;
    for(int i = 0, j = 0, cnt_len = 0; i < range.size(); i++){
      if(++cnt[range[i].second - range[i].first] == 1){
        cnt_len++;
      }
      while(true){
        int len = range[j].second - range[j].first;
        if(cnt[len] == 1){
          break;
        }
        cnt[len]--;
        j++;
      }
      if(cnt_len == n){
        minimize(ans, val[range[i].first][range[i].second] - val[range[j].first][range[j].second]);
      }
    }
    cout << setprecision(12) << fixed << ans;
  }
}
namespace sub4{
  void solve(){
    ld x = calc(1, n);
    vector<pair<ld, int>>val(1, make_pair(x, n));
    for(int len = n - 1; len > 0; len--){
      int low = 1, high = n - len + 1, p;
      while(low <= high){
        int mid = (low + high) >> 1;
        if(calc(mid, mid + len - 1) <= x){
          low = (p = mid) + 1;
        }
        else{
          high = mid - 1;
        }
      }
      val.push_back(make_pair(calc(p, p + len - 1), len));
      val.push_back(make_pair(calc(p + 1, p + len), len));
    }
    sort(val.begin(), val.end());
    vector<int>cnt(n + 1, 0);
    ld ans = 1e9;
    for(int i = 0, j = 0, cnt_len = 0; i < val.size(); i++){
      if(++cnt[val[i].second] == 1){
        cnt_len++;
      }
      while(true){
        if(cnt[val[j].second] == 1){
          break;
        }
        cnt[val[j++].second]--;
      }
      if(cnt_len == n){
        minimize(ans, val[i].first - val[j].first);
      }
    }
    cout << setprecision(12) << fixed << ans;
  }
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if(fopen(taskname".inp", "r")){
		freopen(taskname".inp", "r", stdin);
	}
  cin >> n;
  f[0] = 0;
  for(int i = 1; i <= n; i++){
    cin >> a[i];
    f[i] = f[i - 1] + a[i];
  }
  if(n <= 20){
    sub1::solve();
  }
  else if(n <= 100){
    sub2::solve();
  }
  else if(n <= 2000){
    sub3::solve();
  }
  else{
    sub4::solve();
  }
}

컴파일 시 표준 에러 (stderr) 메시지

seesaw.cpp: In function 'int main()':
seesaw.cpp:165:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  165 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...