, " " ( , - ). - :
std::set<int>
, , , (, , ) ( ). , , , , , (, 15 2 ) -, . , 64- 64 , .
3-4 (log (N)/log (64) , N * log (N)/log (64) -case) . , , , ( 1-2 , , ). , , . ( ). :
typedef void SetResults(int first, int last, void* user_data);
... , C. , , , - , , node 0s, , N * Log (N)/Log (64) , . - std::set<int>
, , . , std::set
. , . , , .
, - , . ( , ). 0, , , . , .
, , 1, , , - , , . 64 (64 ) , SIMD (: 512 ). , , , , 1024 , , , 64 + .
# 2 U
, S
bitwise and
( : S
, ). . FFS/FFZ, .
:
... , , 3 ( , , 1024 + ). S
, 0 , . 1 , .
, 1 U
, , null. , bitwise and
, S
, U
. . , O (N/64 +) (, ), O (N), (64 64- , SIMD).
, , S, .
. , , . , , , (SoA-), , . . , .
However, in this case, if you use one of the two data structures proposed above, you do not need to maintain a separate sequence of random access indexes in order to efficiently find the random one that exists in both sets, since you can find many intersections so quickly and quickly. as you need.