結果
| 問題 |
No.814 ジジ抜き
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 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;
}
qwewe