#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> //#pragma GCC target ("avx2") //#pragma GCC optimize ("Ofast") //#pragma GCC optimize ("unroll-loops") #define f first #define s second #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define sz(x) ((int) (x).size()) #define pb push_back #define mp make_pair #define int long long using namespace std; using namespace __gnu_pbds; template <typename T> using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; template <typename T> inline bool umin(T &a, const T &b) { if(a > b) { a = b; return 1; } return 0; } template <typename T> inline bool umax(T &a, const T &b) { if(a < b) { a = b; return 1; } return 0; } typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; const ll mod = 998244353; const ll base = 1e6 + 9; const ll inf = 1e18; const int MAX = 2e5 + 42; const int LG = 20; //random_device rd; //mt19937 gen(rd()); //uniform_int_distribution<ll> dis(1, inf); vector<int> brute(int m, const vector<array<int, 3>> &a) { vector<int> dp(m, inf); dp[0] = 0; set<pii> q; for(int i = 0; i < m; i++) q.insert({dp[i], i}); while(sz(q)) { auto [val, w] = *q.begin(); q.erase(q.begin()); for(auto [x, y, z] : a) { int nw = (w + y) % m; if(dp[nw] > dp[w] + z) { q.erase({dp[nw], nw}); dp[nw] = dp[w] + z; q.insert({dp[nw], nw}); } } } return dp; } void solve() { int n, m, k; cin >> n >> k >> m; vector<array<int, 3>> a(n); for(auto &[x, y, z] : a) { cin >> x >> y >> z; y %= m; } vector<vector<int>> col(k + 1); for(int i = 0; i < n; i++) col[a[i][0]].pb(i); vector<int> A(m, inf); A[0] = 0; for(int c = 1; c <= k; c++) { vector<int> ndp(m, inf); for(auto i : col[c]) { auto [x, y, z] = a[i]; for(int j = 0; j < m; j++) { int nj = j + y; if(nj >= m) nj -= m; umin(ndp[nj], A[j] + z); } } A = ndp; } vector<int> vals(m, inf); for(int j = 0; j < m; j++) { int val = j; for(int i = 1; i <= m; i++) { int x = inf; if(A[j] <= inf / i) x = A[j] * i; umin(vals[val], x); val += j; if(val >= m) val -= m; } } vector<int> dp(m, inf); dp[0] = 0; for(int i = 0; i < m; i++) { for(int j = 0; j < m; j++) { int nj = i + j; if(nj >= m) nj -= m; umin(dp[nj], dp[j] + vals[i]); } } for(auto i : dp) cout << (i == inf? -1 : i) << '\n'; } signed main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int ttt = 1; // cin >> ttt; while(ttt--) { solve(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> //#pragma GCC target ("avx2") //#pragma GCC optimize ("Ofast") //#pragma GCC optimize ("unroll-loops") #define f first #define s second #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define sz(x) ((int) (x).size()) #define pb push_back #define mp make_pair #define int long long using namespace std; using namespace __gnu_pbds; template <typename T> using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; template <typename T> inline bool umin(T &a, const T &b) { if(a > b) { a = b; return 1; } return 0; } template <typename T> inline bool umax(T &a, const T &b) { if(a < b) { a = b; return 1; } return 0; } typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; const ll mod = 998244353; const ll base = 1e6 + 9; const ll inf = 1e18; const int MAX = 2e5 + 42; const int LG = 20; //random_device rd; //mt19937 gen(rd()); //uniform_int_distribution<ll> dis(1, inf); vector<int> brute(int m, const vector<array<int, 3>> &a) { vector<int> dp(m, inf); dp[0] = 0; set<pii> q; for(int i = 0; i < m; i++) q.insert({dp[i], i}); while(sz(q)) { auto [val, w] = *q.begin(); q.erase(q.begin()); for(auto [x, y, z] : a) { int nw = (w + y) % m; if(dp[nw] > dp[w] + z) { q.erase({dp[nw], nw}); dp[nw] = dp[w] + z; q.insert({dp[nw], nw}); } } } return dp; } void solve() { int n, m, k; cin >> n >> k >> m; vector<array<int, 3>> a(n); for(auto &[x, y, z] : a) { cin >> x >> y >> z; y %= m; } vector<vector<int>> col(k + 1); for(int i = 0; i < n; i++) col[a[i][0]].pb(i); vector<int> A(m, inf); A[0] = 0; for(int c = 1; c <= k; c++) { vector<int> ndp(m, inf); for(auto i : col[c]) { auto [x, y, z] = a[i]; for(int j = 0; j < m; j++) { int nj = j + y; if(nj >= m) nj -= m; umin(ndp[nj], A[j] + z); } } A = ndp; } vector<int> vals(m, inf); for(int j = 0; j < m; j++) { int val = j; for(int i = 1; i <= m; i++) { int x = inf; if(A[j] <= inf / i) x = A[j] * i; umin(vals[val], x); val += j; if(val >= m) val -= m; } } vector<int> dp(m, inf); dp[0] = 0; for(int i = 0; i < m; i++) { for(int j = 0; j < m; j++) { int nj = i + j; if(nj >= m) nj -= m; umin(dp[nj], dp[j] + vals[i]); } } for(auto i : dp) cout << (i == inf? -1 : i) << '\n'; } signed main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int ttt = 1; // cin >> ttt; while(ttt--) { solve(); } } |