結果
問題 |
No.814 ジジ抜き
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:04:11 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 88 ms / 3,000 ms |
コード長 | 4,646 bytes |
コンパイル時間 | 683 ms |
コンパイル使用メモリ | 68,600 KB |
実行使用メモリ | 7,844 KB |
最終ジャッジ日時 | 2025-05-14 13:06:04 |
合計ジャッジ時間 | 4,901 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 23 |
ソースコード
#include <iostream> // Use unsigned long long for integers up to 10^18. // The maximum value of unsigned long long is approximately 1.8 * 10^19. typedef unsigned long long ull; /** * @brief Computes the XOR sum of integers from 0 up to N (inclusive). * * The function utilizes the pattern of XOR sums based on N modulo 4: * G(N) = 0 ^ 1 ^ ... ^ N * G(N) = N if N % 4 == 0 * G(N) = 1 if N % 4 == 1 * G(N) = N+1 if N % 4 == 2 * G(N) = 0 if N % 4 == 3 * * The formula used for calculating the XOR sum of an arithmetic progression relies on G(S-1). * If S=0, S-1 = -1. In unsigned long long, -1 wraps around to ULLONG_MAX. * ULLONG_MAX % 4 = (2^64 - 1) % 4 = 3. * The function correctly returns G(ULLONG_MAX) = 0, which corresponds to G(-1)=0 needed for the formula. * * @param N The upper limit of the range (inclusive). * @return The XOR sum 0 ^ 1 ^ ... ^ N. */ ull G(ull N) { ull rem = N % 4; if (rem == 0) return N; if (rem == 1) return 1; // If rem == 2, the result is N+1. // Using N ^ 1 is equivalent to N+1 for N % 4 == 2 and avoids potential overflow // if N is ULLONG_MAX - 1 (which is congruent to 2 mod 4). if (rem == 2) return N ^ 1; // if rem == 3 return 0; } int main() { // Use fast I/O operations std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int N; // Number of players std::cin >> N; ull total_xor_sum = 0; // Initialize the total XOR sum across all players' cards // Process each player's hand information for (int i = 0; i < N; ++i) { ull K; // Number of cards player i has ull L; // Starting value of the arithmetic progression for player i ull D; // The exponent D_i such that the common difference is 2^D_i std::cin >> K >> L >> D; // The cards player i holds are L, L + 2^D, L + 2*2^D, ..., L + (K-1)*2^D. // We need to compute the XOR sum of these K values. // Decompose L into high and low parts based on D: // L = L_high * 2^D + L_low, where L_low = L % 2^D // Calculate L_high = floor(L / 2^D) using bitwise right shift. // This effectively divides L by 2^D. ull L_high = L >> D; // Calculate L_low = L % 2^D using bitwise AND with a mask. // The mask is (1ULL << D) - 1, which generates a binary number with D ones. // This correctly extracts the lower D bits. // The constraints state D <= 59, so D < 64. This ensures 1ULL << D does not overflow // standard 64-bit unsigned long long and the mask is computed correctly. // If D=0, mask = (1ULL << 0) - 1 = 1 - 1 = 0. L & 0 = 0. Correct. ull mask = (1ULL << D) - 1; ull L_low = L & mask; // The XOR sum computation can be split into contributions from high bits and low bits. // Contribution from higher bits (positions D and above): // This corresponds to the XOR sum of the sequence S, S+1, ..., S+K-1, where S = L_high, // then shifted left by D positions. // The XOR sum of a range [A, B] is G(B) ^ G(A-1). // Here, A = S, B = S+K-1. The sequence is S, S+1, ..., S+K-1. ull S = L_high; // Compute the range bounds for the G function. ull S_plus_K_minus_1 = S + K - 1; // S-1 calculation handles S=0 correctly because unsigned wrap-around to ULLONG_MAX // results in G(ULLONG_MAX) = 0, which matches G(-1)=0. ull S_minus_1 = S - 1; // Compute the XOR sum of the sequence S, S+1, ..., S+K-1 using the G function. ull xor_sum_S_sequence = G(S_plus_K_minus_1) ^ G(S_minus_1); // Shift this value left by D bits to get the contribution from the higher bits part. // The shift is safe because D <= 59. ull contribution_high = xor_sum_S_sequence << D; // Contribution from lower bits (positions 0 to D-1): // Each term L + k*2^D has its lower D bits equal to L_low. // The XOR sum of K identical values L_low is L_low if K is odd, and 0 if K is even. ull contribution_low = (K % 2 != 0) ? L_low : 0; // The total XOR sum for player i is the XOR sum of the high and low parts contributions. ull player_xor_sum = contribution_high ^ contribution_low; // Accumulate this player's XOR sum into the overall total XOR sum. total_xor_sum ^= player_xor_sum; } // The final total XOR sum is the value x we are looking for. std::cout << total_xor_sum << std::endl; return 0; }