/ SeriousOJ /

Record Detail

Accepted


  
# Status Time Cost Memory Cost
#1 Accepted 118ms 23.742 MiB
#2 Accepted 134ms 23.633 MiB
#3 Accepted 154ms 23.586 MiB
#4 Accepted 186ms 23.742 MiB
#5 Accepted 237ms 23.848 MiB
#6 Accepted 226ms 23.969 MiB
#7 Accepted 240ms 24.84 MiB
#8 Accepted 188ms 24.977 MiB
#9 Accepted 170ms 24.863 MiB
#10 Accepted 152ms 24.895 MiB
#11 Accepted 156ms 24.898 MiB
#12 Accepted 276ms 24.812 MiB
#13 Accepted 243ms 25.125 MiB
#14 Accepted 235ms 26.051 MiB
#15 Accepted 272ms 24.055 MiB
#16 Accepted 213ms 23.957 MiB
#17 Accepted 513ms 24.055 MiB
#18 Accepted 272ms 23.969 MiB
#19 Accepted 218ms 24.137 MiB
#20 Accepted 212ms 23.93 MiB

Code

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

// Constants
const int MAX_A = 200005;
const ll INF = 1e18;

// Precompute all divisors for each number up to MAX_A
vector<vector<int>> all_divisors(MAX_A, vector<int>());
void precompute_divisors() {
    for(int g = 1; g < MAX_A; ++g){
        for(int multiple = g; multiple < MAX_A; multiple += g){
            all_divisors[multiple].push_back(g);
        }
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    
    precompute_divisors();
    
    int T;
    cin >> T;
    
    // Initialize min_cost and last_update
    vector<ll> min_cost(MAX_A, INF);
    vector<int> last_update(MAX_A, 0);
    int current_testcase = 1;
    
    while(T--){
        int N, K;
        cin >> N >> K;
        vector<int> A(N+1, 0); // 1-based indexing
        for(int i=1; i<=N; ++i){
            cin >> A[i];
        }
        
        // Initialize DP array
        vector<ll> dp(N+1, INF);
        dp[1] = 0;
        
        // Update min_cost for the first position
        for(auto &g : all_divisors[A[1]]){
            ll temp = dp[1] + (ll)A[1] / g;
            if(last_update[g] != current_testcase || temp < min_cost[g]){
                min_cost[g] = temp;
                last_update[g] = current_testcase;
            }
        }
        
        // Iterate through positions 2 to N
        for(int i=2; i<=N; ++i){
            // Option 1: Move from i-1 to i with cost K
            ll min_val = dp[i-1] + (ll)K;
            
            // Option 2: Jump from any j with GCD(A[j], A[i]) = g
            for(auto &g : all_divisors[A[i]]){
                if(last_update[g] == current_testcase){
                    min_val = min(min_val, min_cost[g]);
                }
            }
            
            dp[i] = min_val;
            
            // Update min_cost for all divisors of A[i]
            for(auto &g : all_divisors[A[i]]){
                ll temp = dp[i] + (ll)A[i] / g;
                if(last_update[g] != current_testcase || temp < min_cost[g]){
                    min_cost[g] = temp;
                    last_update[g] = current_testcase;
                }
            }
        }
        
        cout << dp[N] << "\n";
        current_testcase++;
    }
    
    return 0;
}

Information

Submit By
Type
Submission
Problem
P1099 Which way to go
Language
C++17 (G++ 13.2.0)
Submit At
2024-10-03 20:12:59
Judged At
2024-10-03 20:12:59
Judged By
Score
100
Total Time
513ms
Peak Memory
26.051 MiB