/ SeriousOJ /

Record Detail

Accepted


  
# Status Time Cost Memory Cost
#1 Accepted 1ms 532.0 KiB
#2 Accepted 1ms 532.0 KiB
#3 Accepted 1ms 332.0 KiB
#4 Accepted 1ms 532.0 KiB
#5 Accepted 1ms 488.0 KiB
#6 Accepted 1ms 524.0 KiB
#7 Accepted 1ms 532.0 KiB
#8 Accepted 1ms 532.0 KiB
#9 Accepted 1ms 532.0 KiB
#10 Accepted 1ms 532.0 KiB
#11 Accepted 1ms 344.0 KiB
#12 Accepted 1ms 532.0 KiB
#13 Accepted 1ms 532.0 KiB
#14 Accepted 1ms 520.0 KiB
#15 Accepted 1ms 396.0 KiB
#16 Accepted 1ms 532.0 KiB
#17 Accepted 1ms 532.0 KiB
#18 Accepted 1ms 532.0 KiB
#19 Accepted 1ms 532.0 KiB
#20 Accepted 1ms 496.0 KiB
#21 Accepted 1ms 324.0 KiB
#22 Accepted 1ms 532.0 KiB
#23 Accepted 1ms 324.0 KiB
#24 Accepted 1ms 320.0 KiB
#25 Accepted 1ms 532.0 KiB
#26 Accepted 1ms 532.0 KiB
#27 Accepted 1ms 532.0 KiB
#28 Accepted 1ms 324.0 KiB
#29 Accepted 1ms 352.0 KiB
#30 Accepted 1ms 360.0 KiB
#31 Accepted 1ms 560.0 KiB
#32 Accepted 1ms 532.0 KiB
#33 Accepted 1ms 532.0 KiB
#34 Accepted 2ms 532.0 KiB
#35 Accepted 2ms 320.0 KiB
#36 Accepted 2ms 532.0 KiB
#37 Accepted 2ms 532.0 KiB
#38 Accepted 2ms 532.0 KiB
#39 Accepted 3ms 532.0 KiB
#40 Accepted 4ms 500.0 KiB
#41 Accepted 4ms 444.0 KiB
#42 Accepted 4ms 532.0 KiB
#43 Accepted 4ms 320.0 KiB
#44 Accepted 4ms 532.0 KiB
#45 Accepted 4ms 532.0 KiB
#46 Accepted 4ms 532.0 KiB
#47 Accepted 4ms 532.0 KiB
#48 Accepted 4ms 324.0 KiB
#49 Accepted 4ms 532.0 KiB
#50 Accepted 4ms 536.0 KiB
#51 Accepted 4ms 532.0 KiB
#52 Accepted 4ms 532.0 KiB
#53 Accepted 4ms 532.0 KiB
#54 Accepted 4ms 532.0 KiB
#55 Accepted 4ms 320.0 KiB
#56 Accepted 4ms 532.0 KiB
#57 Accepted 4ms 532.0 KiB
#58 Accepted 4ms 532.0 KiB
#59 Accepted 4ms 532.0 KiB
#60 Accepted 4ms 532.0 KiB
#61 Accepted 4ms 324.0 KiB
#62 Accepted 4ms 532.0 KiB
#63 Accepted 4ms 532.0 KiB
#64 Accepted 4ms 532.0 KiB
#65 Accepted 4ms 532.0 KiB
#66 Accepted 4ms 532.0 KiB
#67 Accepted 4ms 532.0 KiB
#68 Accepted 4ms 532.0 KiB
#69 Accepted 4ms 532.0 KiB
#70 Accepted 4ms 532.0 KiB
#71 Accepted 5ms 536.0 KiB
#72 Accepted 4ms 480.0 KiB
#73 Accepted 4ms 532.0 KiB
#74 Accepted 4ms 320.0 KiB
#75 Accepted 4ms 320.0 KiB
#76 Accepted 4ms 320.0 KiB
#77 Accepted 4ms 532.0 KiB
#78 Accepted 4ms 324.0 KiB
#79 Accepted 4ms 576.0 KiB
#80 Accepted 4ms 532.0 KiB
#81 Accepted 5ms 412.0 KiB
#82 Accepted 335ms 154.734 MiB
#83 Accepted 333ms 154.895 MiB
#84 Accepted 363ms 154.855 MiB
#85 Accepted 346ms 154.891 MiB
#86 Accepted 334ms 154.809 MiB
#87 Accepted 322ms 154.785 MiB
#88 Accepted 335ms 154.781 MiB
#89 Accepted 329ms 154.895 MiB
#90 Accepted 332ms 154.828 MiB
#91 Accepted 334ms 154.887 MiB
#92 Accepted 334ms 154.863 MiB
#93 Accepted 339ms 154.762 MiB
#94 Accepted 362ms 154.957 MiB
#95 Accepted 330ms 154.77 MiB
#96 Accepted 331ms 154.84 MiB
#97 Accepted 332ms 154.77 MiB
#98 Accepted 320ms 154.848 MiB
#99 Accepted 329ms 154.738 MiB
#100 Accepted 349ms 154.875 MiB

Code

#include <bits/stdc++.h>
using namespace std;
 
using ll = long long;
const ll INF = 1LL << 60; // a large number
// We'll set T_max a bit higher than needed; max recursion depth ~ 20.
const int T_max = 22;
 
// Precompute prime factors for numbers in [X, X+T_max].
vector<vector<int>> precomputeFactors(ll X) {
    vector<vector<int>> factors(T_max+1);
    for (int t = 0; t <= T_max; t++) {
        ll Y = X + t;
        ll temp = Y;
        for (ll p = 2; p*p <= temp; p++) {
            if(temp % p == 0) {
                factors[t].push_back(p);
                while(temp % p == 0) temp /= p;
            }
        }
        if(temp > 1) {
            factors[t].push_back((int)temp);
        }
    }
    return factors;
}
 
// For a given a and offset t, compute cost1(a, X+t).
ll cost1(ll a, int t, const vector<vector<int>> &factors) {
    ll ans = INF;
    for (int p : factors[t]) {
        ll r = a % p;
        ll add = (r == 0 ? 0 : p - r);
        ans = min(ans, add);
    }
    return ans;
}
 
// Structure for our game tree node.
struct Node {
    int L, R;
    Node *left = nullptr, *right = nullptr;
    // dp[t]: minimum operations to make the segment (with parameter X+t)-ordinary.
    // cost[t]: cost to fix every element in the segment so that gcd(element, X+t) > 1.
    array<ll, T_max+1> dp;
    array<ll, T_max+1> cost;
};
 
// Global array and factors (for base cost computation).
vector<ll> A;
 
// Build the tree using the fixed splitting rule for indices [L, R] (0-indexed).
Node* buildTree(int L, int R, const vector<vector<int>> &factors, ll X) {
    Node *node = new Node();
    node->L = L; node->R = R;
    int n = R - L + 1;
    if(n == 1) {
        // Leaf node: for each t compute cost1(A[L], X+t)
        for (int t = 0; t <= T_max; t++) {
            ll c = cost1(A[L], t, factors);
            node->dp[t] = c;
            node->cost[t] = c;
        }
        return node;
    }
    // Determine the split:
    int k = n / 2; // first half size = floor(n/2)
    int mid = L + k; // left: [L, mid-1], right: [mid, R]
    node->left = buildTree(L, mid - 1, factors, X);
    node->right = buildTree(mid, R, factors, X);
    // Combine children:
    for (int t = 0; t <= T_max; t++) {
        // The cost to fix the whole segment for parameter X+t is the sum over children.
        node->cost[t] = node->left->cost[t] + node->right->cost[t];
    }
    // For dp[t], we need dp[t+1] from children.
    for (int t = 0; t <= T_max; t++) {
        if(t == T_max) {
            // Not enough parameter "budget" for recursive call.
            node->dp[t] = INF;
        } else {
            ll option1 = node->left->dp[t+1] + node->right->cost[t];
            ll option2 = node->right->dp[t+1] + node->left->cost[t];
            node->dp[t] = min(option1, option2);
        }
    }
    return node;
}
 
// Free the allocated tree.
void freeTree(Node *node) {
    if(!node) return;
    freeTree(node->left);
    freeTree(node->right);
    delete node;
}
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int N; 
    ll X;
    cin >> N >> X;
    A.resize(N);
    for (int i = 0; i < N; i++){
        cin >> A[i];
    }
    if(X == 1) {
     cout << -1 << '\n';
     return 0;
    }
    // Precompute factors for X, X+1, ..., X+T_max.
    vector<vector<int>> factors = precomputeFactors(X);
    
    // Build the game tree for the entire array [0, N-1].
    Node *root = buildTree(0, N-1, factors, X);
    
    // The answer is the minimum number of operations to make the whole array X-ordinary,
    // which is stored in root->dp[0].
    ll answer = root->dp[0];
    cout << answer << "\n";
    
    freeTree(root);
    return 0;
}

Information

Submit By
Type
Submission
Problem
P1168 F. x ordinary array
Language
C++17 (G++ 13.2.0)
Submit At
2025-03-28 22:26:06
Judged At
2025-03-28 22:26:06
Judged By
Score
100
Total Time
363ms
Peak Memory
154.957 MiB