#include #include #include #include #include #define int long long using namespace std; mt19937 mt(7623765); class TestCase { public: int N, K, seed, a, b, m; vector f, w, v; vector values[4]; //values[weight] = 価値リスト private: bool is_valid() { if (N <= 0 || N > 1000000) return false; if (K <= 0 || K > N) return false; if (m <= 2 || m > 1000000000) return false; if (a <= 0 || a >= m) return false; if (b <= 0 || b >= m) return false; if (seed <= 0 || seed >= m) return false; return true; } void generate_fwv() { f.resize(2 * N); f[0] = seed; for (int i = 1; i < 2 * N; i++) { f[i] = (a * f[i - 1] + b) % m; } w.resize(N); for (int i = 0; i < N; i++) { w[i] = f[i] % 3 + 1; } v.resize(N); for (int i = 0; i < N; i++) { v[i] = w[i] * f[N + i]; } } void generate_values() { for (int i = 0; i < N; i++) { values[w[i]].push_back(v[i]); } } public: void input() { cin >> N >> K >> seed >> a >> b >> m; assert(is_valid()); generate_fwv(); generate_values(); } void generate(int N) { this->N = N; K = mt() % N + 1; m = mt() % 999999998 + 3; a = mt() % (m - 1) + 1; b = mt() % (m - 1) + 1; seed = mt() % (m - 1) + 1; assert(is_valid()); generate_fwv(); generate_values(); } void print() { printf("N = %lld, K = %lld, seed = %lld, a = %lld, b = %lld, m = %lld\n", N, K, seed, a, b, m); for (int i = 1; i <= 3; i++) { for (int j = 0; j < values[i].size(); j++) { cout << values[i][j]; if (j + 1 < values[i].size()) cout << " "; } cout << endl; } } }; class Solver { protected: int N, K; vector values[4]; void input(TestCase &testcase) { N = testcase.N; K = testcase.K; for (int i = 0; i < 4; i++) { values[i] = testcase.values[i]; } } public: virtual int solve(TestCase &testcase) = 0; }; class NaiveSolver : public Solver { public: int solve(TestCase &testcase) { input(testcase); for (int i = 1; i <= 3; i++) { sort(values[i].begin(), values[i].end(), greater()); } vector sum_values[4]; //sum_values[weight][count] = 重さ合計 for (int i = 1; i <= 3; i++) { sum_values[i].resize(values[i].size() + 1); sum_values[i][0] = 0; for (int j = 0; j < values[i].size(); j++) { sum_values[i][j + 1] = sum_values[i][j] + values[i][j]; } } int ans = 0; for (int i = 0; i <= values[1].size(); i++) { for (int j = 0; j <= values[2].size(); j++) { for (int k = 0; k <= values[3].size(); k++) { int box_count = k + j + (max(0LL, i - j) + 2) / 3; if (box_count <= K) { ans = max(ans, sum_values[1][i] + sum_values[2][j] + sum_values[3][k]); } } } } return ans; } }; class FastSolver : public Solver { vector sum_values[4]; int sum_values_func(int weight, int cnt) { if (cnt < sum_values[weight].size()) { return sum_values[weight][cnt]; } return sum_values[weight][values[weight].size()]; } //重さ2をx個使うとしたとき、重さ1, 2の荷物を容量3のナップザックに詰めるときの価値和のmaxは? int f(int x, int i) { return sum_values[2][i] + sum_values_func(1, 3 * x - 2 * i); } //重さ1, 2の荷物を、容量3のナップザックx個に詰めるときの、詰める荷物の価値和の最大値 int f(int x) { //f(x, i + 1) - f(x, i) <= 0になる最小のiは?0 <= i < c_2, 無ければc_2. int c_2 = min(x, (int)values[2].size()); int ng = -1, ok = c_2, mid; //(ng, ok] while (ok - ng >= 2) { mid = (ng + ok) / 2; if (f(x, mid + 1) - f(x, mid) <= 0) { ok = mid; } else { ng = mid; } } return f(x, ok); } public: int solve(TestCase &testcase) { input(testcase); for (int i = 1; i <= 3; i++) { sort(values[i].begin(), values[i].end(), greater()); sum_values[i].resize(values[i].size() + 1); sum_values[i][0] = 0; for (int j = 0; j < values[i].size(); j++) { sum_values[i][j + 1] = sum_values[i][j] + values[i][j]; } } int ans = 0; for (int i = 0; i <= min(K, (int)values[3].size()); i++) { //重さ3をi個使う int res = sum_values[3][i] + f(K - i); ans = max(ans, res); } return ans; } }; FastSolver fast; signed main() { TestCase test; test.input(); cout << fast.solve(test) << endl; return 0; }