cppAcademy
FROM LEARNING TO COMPETING

Expert.
Put your skills to the test.

Bulgarian Informatics Group A · 2009–2026

217 independently explained problems: 54 Municipal, 54 Regional and 109 National. Start with the easier tasks and work upwards. Difficulty labels are learning estimates, not official ratings; Group A also includes challenging national-level problems. The 109 National-round tasks shared by Groups A and B retain their existing permanent URLs and explanations. Years follow Arena’s competition-season labels. Source clarifications and special grader requirements are noted on affected tasks.
GROUP A2011 · MediumBitwise XOR

Eavesdropping

National Olympiad — Regional round (2011 season)

Submission name: pircos.cpp

Problem summary

An unordered stream contains every object number exactly twice, except two distinct numbers that occur once. Find the two singletons under a very small memory limit.

Input

Even N, then N natural numbers.

Output

The two singleton numbers in increasing order.

Constraints

2 ≤ N ≤ 1000000, even; object numbers have at most 18 decimal digits; total memory allowance is 512 KB.

Worked example

Official statement example.

Input

10
14
7
21
9
14
17
17
7
19
9

Output

19 21

Solution analysis

  1. The XOR of the stream is a XOR b, because every repeated value cancels. A set bit in this XOR distinguishes the two singletons. The usual two-pass solution partitions values by that bit, but the stream cannot be reread or stored here.
  2. Instead keep 60 XOR accumulators, one per possible bit. When reading a number, XOR it into every accumulator whose bit is set in that number. Also maintain the overall XOR. Once the stream ends, choose any set bit of the overall XOR. Its accumulator contains exactly the singleton having that bit set.
  3. The other singleton is obtained by XOR with the overall XOR; sort the pair. In the sample, repeated numbers cancel and the two remaining numbers are 19 and 21. Sixty 64-bit accumulators use only 480 bytes.

Why it works

For a chosen bit each repeated number either enters its accumulator twice or never, so it cancels. At any set bit of a XOR b exactly one singleton enters, leaving precisely that number. The other is recovered by XOR. Because the singletons differ, at least one such bit exists.

Complexity: O(60N) time and O(60) machine words of working storage.

Watch out. Do not require a second input pass.,18 decimal digits require 64-bit storage.,The two singletons are distinct, so their XOR is nonzero.

Commented C++17 solution

Uses C stdio and 60 fixed accumulators so no input-sized memory or second pass is required. The historical 512 KB limit includes implementation-dependent runtime overhead; the algorithmic storage is below 1 KB.

// Key idea: For a chosen bit each repeated number either enters its accumulator twice or never, so it
// cancels. At any set bit of a XOR b exactly one singleton enters, leaving precisely that number.
#include<cstdio>
#include<cstdint>
using namespace std;
int main(){
    int n;
    if(scanf("%d",&n)!=1){
        return 0;
    }
    unsigned long long bucket[60]={},total=0;
    for(int i=0;i<n;++i){
        unsigned long long value;
        if(scanf("%llu",&value)!=1){
            return 0;
        }
        total^=value;
        unsigned long long bits=value;
        for(int bit=0;bits!=0;++bit){
            if(bits&1ULL){
                bucket[bit]^=value;
            }
            bits>>=1;
        }
    }
    int bit=0;
    while(((total>>bit)&1ULL)==0){
        ++bit;
    }
    unsigned long long a=bucket[bit],b=total^a;
    if(a>b){
        unsigned long long temporary=a;
        a=b;
        b=temporary;
    }
    printf("%llu %llu\n",a,b);
}

Source: Arena Olimpiici ↗