結果
問題 |
No.1067 #いろいろな色 / Red and Blue and more various colors (Middle)
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:24:01 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 5,818 bytes |
コンパイル時間 | 1,000 ms |
コンパイル使用メモリ | 90,332 KB |
実行使用メモリ | 16,064 KB |
最終ジャッジ日時 | 2025-05-14 13:25:28 |
合計ジャッジ時間 | 5,067 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 10 TLE * 1 -- * 14 |
ソースコード
#include <iostream> #include <vector> #include <numeric> #include <algorithm> #include <map> using namespace std; const long long MOD = 998244353; // Computes Q(x) = P(x) / (x + term_val) // p_coeffs: coefficients of P(x) // q_coeffs: output coefficients of Q(x) // p_actual_degree: actual degree of P(x) // coeffs_array_size: allocated size of p_coeffs and q_coeffs arrays (max_coeffs_stored + 1) void poly_divide_by_linear(const vector<long long>& p_coeffs, vector<long long>& q_coeffs, long long term_val, int p_actual_degree, int coeffs_array_size) { fill(q_coeffs.begin(), q_coeffs.begin() + coeffs_array_size, 0); if (p_actual_degree < 0) p_actual_degree = 0; // Should not happen, but defensive if (p_actual_degree == 0) { // P(x) is a constant. If (x+term_val) was a factor, P(x) must have been 0. // The resulting polynomial Q(x) is 0. q_coeffs is already filled with 0. return; } // q_{D-1} = p_D q_coeffs[p_actual_degree - 1] = p_coeffs[p_actual_degree]; // For k from D-1 down to 1: q_{k-1} = p_k - term_val * q_k for (int k = p_actual_degree - 1; k >= 1; --k) { long long val_q_k = q_coeffs[k]; q_coeffs[k - 1] = (p_coeffs[k] - (term_val * val_q_k) % MOD + MOD) % MOD; } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n, q_count; cin >> n >> q_count; vector<long long> a_arr(n); map<long long, int> a_freq; for (int i = 0; i < n; ++i) { cin >> a_arr[i]; a_freq[a_arr[i]]++; } vector<long long> query_results_final; for (int qi = 0; qi < q_count; ++qi) { long long l_query, r_query, p_target; cin >> l_query >> r_query >> p_target; int s_range = r_query - l_query; // max_coeffs_stored is the highest DEGREE we might need for p_coeffs int max_coeffs_stored = p_target + s_range; if (max_coeffs_stored > n) max_coeffs_stored = n; // p_coeffs array stores coefficients from degree 0 to max_coeffs_stored // Its size is max_coeffs_stored + 1 vector<long long> p_coeffs(max_coeffs_stored + 1, 0); p_coeffs[0] = 1; long long k_val = 1; int current_poly_actual_degree = 0; for (int i = 0; i < n; ++i) { if (a_arr[i] >= l_query) { long long term_const = (a_arr[i] - 1 + MOD) % MOD; int next_poly_degree = min(n, current_poly_actual_degree + 1); // Loop k from highest possible degree downwards for (int k = min(next_poly_degree, max_coeffs_stored); k >= 0; --k) { long long prev_coeff_val = (k > 0) ? p_coeffs[k - 1] : 0; // Coeff of x^(k-1) from previous poly long long current_coeff_val_times_const = (p_coeffs[k] * term_const) % MOD; p_coeffs[k] = (current_coeff_val_times_const + prev_coeff_val) % MOD; } current_poly_actual_degree = next_poly_degree; } else { k_val = (k_val * a_arr[i]) % MOD; } } long long total_xor_sum = 0; vector<long long> temp_q_coeffs(max_coeffs_stored + 1); for (long long c = l_query; c <= r_query; ++c) { long long needed_p_coeff_val = 0; if (p_target <= current_poly_actual_degree && p_target <= max_coeffs_stored) { needed_p_coeff_val = p_coeffs[p_target]; } long long term_result = (k_val * needed_p_coeff_val) % MOD; total_xor_sum ^= term_result; if (c < r_query) { int num_aj_equal_c = 0; if (a_freq.count(c)) { num_aj_equal_c = a_freq[c]; } if (num_aj_equal_c > 0) { for (int k_iter = 0; k_iter < num_aj_equal_c; ++k_iter) { k_val = (k_val * c) % MOD; // Check if polynomial is not already zero or degree effectively < 0 if (current_poly_actual_degree >= 0) { long long term_to_divide_val = (c - 1 + MOD) % MOD; poly_divide_by_linear(p_coeffs, temp_q_coeffs, term_to_divide_val, current_poly_actual_degree, max_coeffs_stored + 1); p_coeffs.swap(temp_q_coeffs); // Efficiently swap contents current_poly_actual_degree--; } else { // Polynomial is already 0. Division keeps it 0. // This state means current_poly_actual_degree can be -1, -2 etc. // p_coeffs should be all zeros if degree is <0 fill(p_coeffs.begin(), p_coeffs.end(), 0); } } } // Normalize degree if it went negative, polynomial 0 has degree usually undefined or -1, for practical purposes 0 is fine for array access if it means coeff[0] could be non-zero. // If current_poly_actual_degree becomes < 0, it implies the polynomial is identically zero. // For safety, if it's < 0, all its coefficients should be zero. if(current_poly_actual_degree < 0) { fill(p_coeffs.begin(), p_coeffs.begin() + max_coeffs_stored + 1, 0); } } } query_results_final.push_back(total_xor_sum); } for (int i = 0; i < query_results_final.size(); ++i) { cout << query_results_final[i] << (i == query_results_final.size() - 1 ? "" : "\n"); } if (!query_results_final.empty()) { cout << endl; } return 0; }