제출 #1331720

#제출 시각아이디문제언어결과실행 시간메모리
1331720SmuggingSpunText editor (CEOI24_editor)C++20
100 / 100
1026 ms462032 KiB
#include<bits/stdc++.h>
#define taskname "C"
using namespace std;
typedef long long ll;
template<class T>bool minimize(T& a, T b){
  if(a > b){
    a = b;
    return true;
  }
  return false;
}
const int lim = 1e6 + 5;
const ll INF = 1e18;
int n, sl, sc, tl, tc, l[lim];
namespace sub2{
  void solve(){
    vector<vector<int>>f(n + 1);
    for(int i = 1; i <= n; i++){
      f[i].assign(l[i] + 2, -1);
    }
    queue<pair<int, int>>q;
    q.push(make_pair(sl, sc));
    f[sl][sc] = 0;
    auto work = [&] (int yl, int yc, int v){
      if(f[yl][yc] == -1){
        f[yl][yc] = v;
        q.push(make_pair(yl, yc));
      }
    };
    while(!q.empty()){
      int xl, xc;
      tie(xl, xc) = q.front();
      q.pop();
      int v = f[xl][xc] + 1;
      if(xc > 1){
        work(xl, xc - 1, v);
      }
      else if(xl > 1){
        work(xl - 1, l[xl - 1] + 1, v);
      }
      if(xc <= l[xl]){
        work(xl, xc + 1, v);
      }
      else if(xl < n){
        work(xl + 1, 1, v);
      }
      if(xl > 1){
        work(xl - 1, min(xc, l[xl - 1] + 1), v);
      }
      if(xl < n){
        work(xl + 1, min(xc, l[xl + 1] + 1), v);
      }
    }
    cout << f[tl][tc];
  }
}
namespace sub134{
  struct Edge{
    int i, j, w;
    Edge(){}
    Edge(int _i, int _j, int _w) : i(_i), j(_j), w(_w) {}
  };
  struct Data{
    int i, j;
    ll w;
    Data(){}
    Data(int _i, int _j, ll _w) : i(_i), j(_j), w(_w) {}
    friend bool operator <(const Data a, const Data b){
      return a.w > b.w;
    }
  };
  void solve(){
    vector<int>point(l + 1, l + n + 1);
    point.push_back(sc - 1);
    point.push_back(tc - 1);
    sort(point.begin(), point.end());
    point.resize(unique(point.begin(), point.end()) - point.begin());
    for(int& x : point){
      x++;
    }
    int m = point.size();
    auto pid = [&] (int i){
      return lower_bound(point.begin(), point.end(), i) - point.begin();
    };
    vector<vector<vector<Edge>>>g(n + 1, vector<vector<Edge>>(m));
    for(int i = 1; i <= n; i++){
      for(int j = 0; j + 1 < m && point[j] < l[i] + 2; j++){
        g[i][j].push_back(Edge(i, j + 1, point[j + 1] - point[j]));
      }
      if(i > 1){
        int last = pid(l[i - 1] + 1);
        g[i][0].push_back(Edge(i - 1, last, 1));
        for(int j = 0; j < m && point[j] < l[i] + 2; j++){
          g[i][j].push_back(Edge(i - 1, min(last, j), 1));
        }
      }
      if(i < n){
        g[i][pid(l[i] + 1)].push_back(Edge(i + 1, 0, 1));
        for(int j = 0, last = pid(l[i + 1] + 1); j < m && point[j] < l[i] + 2; j++){
          g[i][j].push_back(Edge(i + 1, min(last, j), 1));
        }
      }
    }
    priority_queue<Data>pq;
    vector<vector<ll>>d(n + 1, vector<ll>(m, INF));
    pq.push(Data(sl, pid(sc), d[sl][pid(sc)] = 0));
    while(!pq.empty()){
      Data u = pq.top();
      pq.pop();
      if(u.w == d[u.i][u.j]){
        for(auto& [ei, ej, ew] : g[u.i][u.j]){
          if(minimize(d[ei][ej], u.w + ew)){
            pq.push(Data(ei, ej, d[ei][ej]));
          }
        }
      }
    }
    ll ans = INF;
    for(int i = 0; i < m; i++){
      minimize(ans, d[tl][i] + abs(point[i] - tc));
    }
    cout << ans;
  }
}
namespace sub5{
  int smin[lim], tmin[lim];
  ll f[lim];
  void solve(){
    smin[sl] = l[sl] + 1;
    for(int i = sl - 1; i > 0; i--){
      smin[i] = min(smin[i + 1], l[i] + 1);
    }
    for(int i = sl + 1; i <= n; i++){
      smin[i] = min(smin[i - 1], l[i] + 1);
    }
    tmin[tl] = l[tl] + 1;
    for(int i = tl - 1; i > 0; i--){
      tmin[i] = min(tmin[i + 1], l[i] + 1);
    }
    for(int i = tl + 1; i <= n; i++){
      tmin[i] = min(tmin[i - 1], l[i] + 1);
    }
    ll ans = INF;
    memset(f, 0x0f, sizeof(f));
    for(int i = 1; i <= n; i++){
      minimize(ans, ll(abs(sl - i)) + abs(i - tl) + abs(min({smin[i], tmin[i], sc}) - tc));
      minimize(f[i], ll(abs(sl - i)) + (min(smin[i], sc) - 1));
      if(i < n){
        minimize(f[i + 1], ll(abs(sl - i)) + (l[i] + 2 - min(smin[i], sc)));
      }
    }
    ll min_f = INF;
    for(int i = 1; i <= n; i++){
      minimize(f[i], min_f + i);
      minimize(min_f, f[i] - i);
    }
    min_f = INF;
    for(int i = n; i > 0; i--){
      minimize(f[i], min_f - i);
      minimize(min_f, f[i] + i);
      minimize(ans, f[i] + abs(i - tl) + tc - 1);
    }
    for(int i = 2; i <= n; i++){
      minimize(ans, f[i] + 1 + abs(i - 1 - tl) + abs(tmin[i - 1] - tc));
    }
    cout << 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 >> sl >> sc >> tl >> tc;
  for(int i = 1; i <= n; i++){
    cin >> l[i];
  }
  if(n <= 1000 && *max_element(l + 1, l + n + 1) <= 5000){
    sub2::solve();
  }
  else if(n <= 1000 || count(l + 1, l + n, l[1]) == n - 1){
    sub134::solve();
  }
  else{
    sub5::solve();
  }
}

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

Main.cpp: In function 'int main()':
Main.cpp:172:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  172 |                 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...