Submission #1132160

#TimeUsernameProblemLanguageResultExecution timeMemory
1132160Math4Life2020Copy and Paste 3 (JOI22_copypaste3)C++20
62 / 100
3082 ms558252 KiB
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
#include <bits/stdc++.h>
using namespace std;
using ll = long long; using pii = pair<ll,ll>;

const ll Nm = 2505; const ll INF = 1e18;
const ll a1 = 123456789; const ll p1 = ((ll)1e9+7);
ll s1[Nm+1];
ll expa1[Nm+1];
ll hsh1[Nm+1];
ll N; string s;
ll A,B,C;

gp_hash_table<ll,ll> dp[Nm+1]; //dp[len][hsh] -> val
map<pii,vector<ll>> locs; //{len,hsh} -> vector of positions

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    cin >> N >> s >> A >> B >> C;
    expa1[0]=1;
    hsh1[0]=0;
    for (ll i=0;i<Nm;i++) {
        expa1[i+1]=(a1*expa1[i])%p1;
        s1[i]=s[i]-'a'+1;
        hsh1[i+1]=(a1*hsh1[i]+s[i]-'a'+1)%p1;
    }
    for (ll i=0;i<N;i++) {
        for (ll j=(i+1);j<=N;j++) {
            ll hv = hsh1[j]-expa1[j-i]*hsh1[i];
            hv = (hv + p1*(2-hv/p1))%p1;
            dp[j-i][hv]=INF;
            locs[{j-i,hv}].push_back(i);
        }
    }
    dp[0][0]=0;
    for (ll L=1;L<=N;L++) {
        for (ll i=0;i<=(N-L);i++) {
            ll hv0 = hsh1[i+L-1]-expa1[L-1]*hsh1[i];
            hv0 = (hv0 + p1*(2-hv0/p1))%p1;
            ll hv1 = (a1*hv0 + s1[i+L-1])%p1;
            ll hv2 = hsh1[i+L]-expa1[L-1]*hsh1[i+1];
            hv2 = (hv2 + p1*(2-hv2/p1))%p1;
            dp[L][hv1] = min(dp[L][hv1],A+dp[L-1][hv0]);
            dp[L][hv1] = min(dp[L][hv1],A+dp[L-1][hv2]); 
        }
        for (pii p0: dp[L]) {
            ll hsh = p0.first; ll dpv = p0.second;
            if (locs[{L,hsh}].size()==1) {continue;}
            vector<ll> vlc = locs[{L,hsh}];
            sort(vlc.begin(),vlc.end());
            for (ll x: vlc) {
                ll y = x;
                ll njp = 0;
                while(1) {
                    auto A0 = lower_bound(vlc.begin(),vlc.end(),y);
                    if (A0==vlc.end()) {
                        break;
                    } else {
                        njp++;
                        y = (*A0)+L;
                        //string chars in range [x,y)
                        ll hv0 = hsh1[y]-hsh1[x]*expa1[y-x];
                        hv0 = (hv0+p1*(2-hv0/p1))%p1;
                        dp[y-x][hv0]=min(dp[y-x][hv0],A*(y-x-njp*L)+B+dpv+C*njp);
                    }
                }
            }
        }
    }
    cout << dp[N][hsh1[N]] <<"\n";
}

//for a stored sub-block S0 (length x): 
//x starting positions
//if O-tilde(#(occurrences of S0)^2):
//sum over x=x0: O(N^2) worst case -> bad.
//wait no: should (???) amortize to O(N^2logN)???
//ok imma code it
#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...