제출 #1351838

#제출 시각아이디문제언어결과실행 시간메모리
1351838SmuggingSpunCopy and Paste 3 (JOI22_copypaste3)C++20
100 / 100
2362 ms775872 KiB
#include<bits/stdc++.h>
#define taskname "A"
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 ll INF = 1e18;
int n, a, b, c;
string s;
namespace sub2{
  struct Data{
    int sx, sy;
    ll w;
    Data(){}
    Data(int _sx, int _sy, ll _w) : sx(_sx), sy(_sy), w(_w) {}
    friend bool operator <(const Data a, const Data b){
      return a.w > b.w;
    }
  };
  void solve(){
    vector<vector<ll>>f(n + 1, vector<ll>(n + 1, INF));
    priority_queue<Data>pq;
    pq.push(Data(0, 0, f[0][0] = 0));
    while(!pq.empty()){
      Data u = pq.top();
      pq.pop();
      if(u.w == f[u.sx][u.sy]){
        if(u.sx < n && minimize(f[u.sx + 1][u.sy], u.w + a)){
          pq.push(Data(u.sx + 1, u.sy, u.w + a));
        }
        if(minimize(f[0][u.sx], u.w + b)){
          pq.push(Data(0, u.sx, u.w + b));
        }
        if(u.sx + u.sy <= n && minimize(f[u.sx + u.sy][u.sy], u.w + c)){
          pq.push(Data(u.sx + u.sy, u.sy, u.w + c));
        }
      }
    }
    cout << *min_element(f[n].begin(), f[n].end());
  }
}
namespace sub13{
  const int lim = 35;
  ll f[lim][lim][lim][lim];
  bool is_equal(int l1, int r1, int l2, int r2){
    if(r1 - l1 != r2 - l2){
      return false;
    }
    for(int i = l1, j = l2; i <= r1; i++, j++){
      if(s[i] != s[j]){
        return false;
      }
    }
    return true;
  }
  struct Data{
    int lx, rx, ly, ry;
    ll w;
    Data(){}
    Data(int _lx, int _rx, int _ly, int _ry, ll _w) : lx(_lx), rx(_rx), ly(_ly), ry(_ry), w(_w) {}
    friend bool operator <(const Data a, const Data b){
      return a.w > b.w;
    }
  };
  priority_queue<Data>pq;
  void work(int lx, int rx, int ly, int ry, ll w){
    if(minimize(f[lx][rx][ly][ry], w)){
      pq.push(Data(lx, rx, ly, ry, w));
    }
  }
  void solve(){
    memset(f, 0x0f, sizeof(f));
    pq.push(Data(0, 0, 0, 0, f[0][0][0][0] = 0));
    while(!pq.empty()){
      auto [lx, rx, ly, ry, w] = pq.top();
      pq.pop();
      if(lx == 1 && rx == n){
        return void(cout << w);
      }
      if(w == f[lx][rx][ly][ry]){
        if(rx < n){
          work(max(lx, 1), rx + 1, ly, ry, w + a);
        }
        work(0, 0, lx, rx, w + b);
        if(ry > 0 && rx + (ry - ly + 1) <= n && is_equal(rx + 1, rx + ry - ly + 1, ly, ry)){
          work(max(lx, 1), rx + ry - ly + 1, ly, ry, w + c);
        }
        if(lx == 0){
          for(int i = 1; i <= n; i++){
            work(i, i, ly, ry, w + a);
          }
        }
      }
    }
  }
}
namespace sub456{
  const int lim = 2502;
  const int LG = 11;
  struct Node{
    vector<int>p;
    int c[26];
    Node(){
      memset(c, -1, sizeof(c));
    }
  };
  vector<Node>trie(1, Node());
  struct Data{
    int l, r, cnt;
    Data(){}
    Data(int _l, int _r, int _cnt) : l(_l), r(_r), cnt(_cnt) {}
  };
  vector<Data>care[(lim * lim) >> 1];
  ll f[lim][lim], nf[lim][lim];
  void dfs_1(int v, int len){
    vector<int>& ve = trie[v].p;
    for(int l = 0; l < ve.size(); l++){
      for(int r = l, last = -1, cnt = 0; r < ve.size(); r++){
        if(ve[r] > last){
          care[v].push_back(Data(ve[l], last = ve[r] + len - 1, ++cnt));
        }
      }
    }
    for(int i = 0; i < 26; i++){
      if(trie[v].c[i] != -1){
        dfs_1(trie[v].c[i], len + 1);
      }
    }
  }
  void dfs_2(int v, int len){
    for(auto& [l, r, cnt] : care[v]){
      minimize(nf[l][r], f[l][l + len - 1] + b + ll(c) * cnt + ll(a) * (r - l + 1 - len * cnt));
    }
    for(int i = 0; i < 26; i++){
      if(trie[v].c[i] != -1){
        dfs_2(trie[v].c[i], len + 1);
      }
    }
  }
  void solve(){
    for(int i = 1; i <= n; i++){
      s[i] -= 'a';
    }
    for(int l = 1; l <= n; l++){
      int v = 0;
      for(int r = l; r <= n; r++){
        if(trie[v].c[s[r]] == -1){
          trie[v].c[s[r]] = trie.size();
          trie.push_back(Node());
        }
        trie[v = trie[v].c[s[r]]].p.push_back(l);
        f[l][r] = nf[l][r] = ll(a) * (r - l + 1);
      }
    }
    dfs_1(0, 0);
    for(int _ = 0; _ < LG; _++){
      dfs_2(0, 0);
      for(int len = 1; len < n; len++){
        for(int r = len + 1; r <= n; r++){
          int l = r - len;
          minimize(nf[l][r], min(nf[l][r - 1], nf[l + 1][r]) + a);
        }
      }
      memcpy(f, nf, sizeof(f));
    }
    cout << f[1][n];
  }
}
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 >> s >> a >> b >> c;
  s = '#' + s;
  if(count(s.begin(), s.end(), 'a') == n){
    sub2::solve();
  }
  else if(n <= 30){
    sub13::solve();
  }
  else{
    sub456::solve();
  }
}

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

copypaste3.cpp: In function 'int main()':
copypaste3.cpp:177:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  177 |                 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...