• + 0 comments

    Working one. No more sprawling sets.

    #include <iostream>
    #include <vector>
    using namespace std;
    
    bool seenIT(unsigned long long sCurrent, vector<unsigned long long>& seen) {
        size_t blk = sCurrent >> 6;
        unsigned long long slot = 1ULL << (sCurrent & 63);
        if (seen[blk] & slot) return true;
        seen[blk] |= slot;
        return false;
    }
    
    int main() {
        unsigned long long n, s, p, q;
        cin >> n >> s >> p >> q;
    
        const unsigned long long RANGE = 1U << 31;            //this many different #s
        size_t blocks = (RANGE + 63) / 64;
        vector<unsigned long long> seen(blocks, 0);         //All start as 0, unseen
        seenIT(s, seen);
        
        bool earlyOut = false;
        for (int i = 1; i < n; i++) {
            s = (s * p + q) % RANGE;
            if (seenIT(s, seen)) {
                earlyOut = true;
                cout << i;
                break;
            }
        }
        if (!earlyOut)
            cout << n;
    
        return 0;
    }