#include <iostream>
#include <iterator>
#include <algorithm>
#include <numeric>
#include <thread>
#include <vector>
std::size_t count_needle(int * first, int *const last,
int const* needleFirst, int const* const needleLast) {
std::sort(first, last);
std::size_t count = 0;
while (first != last && needleFirst != needleLast) {
if (*first == *needleFirst) {
++count;
++first;
} else if (*needleFirst < *first) {
++needleFirst;
} else {
++first;
}
}
return count;
}
int main()
{
int arrayFirst[] = { 11, 5, 2, 8, 4, 5, 2, 5, 7, 9, 12, 16, 17, 18, 20 };
int arraySecond[] = { 22, 5, 8, 3, 2, 9, 4, 3, 9, 10 };
std::sort(std::begin(arraySecond), std::end(arraySecond));
auto const arraySecondEnd = std::unique(std::begin(arraySecond), std::end(arraySecond));
auto const numThreads = std::thread::hardware_concurrency();
std::vector<std::thread> tasks;
tasks.reserve(numThreads);
std::vector<size_t> results(numThreads);
auto const firstSize = sizeof(arrayFirst) / sizeof(*arrayFirst);
auto const firstStep = (firstSize + numThreads - 1) / numThreads;
for (std::size_t i = 0; i != numThreads; ++i) {
auto const firstBegin = arrayFirst + i * firstStep;
auto const firstEnd = arrayFirst + std::min((i + 1) * firstStep, firstSize);
std::thread task([=, &results] () {
results[i] = count_needle(firstBegin, firstEnd, arraySecond, arraySecondEnd);
});
tasks.push_back(std::move(task));
}
for (auto & task : tasks) {
task.join();
}
auto const count = std::accumulate(std::begin(results), std::end(results), std::size_t(0));
std::cout << count << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxudW1lcmljPgojaW5jbHVkZSA8dGhyZWFkPgojaW5jbHVkZSA8dmVjdG9yPgoKCnN0ZDo6c2l6ZV90IGNvdW50X25lZWRsZShpbnQgKiBmaXJzdCwgaW50ICpjb25zdCBsYXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvbnN0KiBuZWVkbGVGaXJzdCwgaW50IGNvbnN0KiBjb25zdCBuZWVkbGVMYXN0KSB7CiAgIHN0ZDo6c29ydChmaXJzdCwgbGFzdCk7CiAgIAogICBzdGQ6OnNpemVfdCBjb3VudCA9IDA7CiAgIHdoaWxlIChmaXJzdCAhPSBsYXN0ICYmIG5lZWRsZUZpcnN0ICE9IG5lZWRsZUxhc3QpIHsKICAgICAgaWYgKCpmaXJzdCA9PSAqbmVlZGxlRmlyc3QpIHsKICAgICAgICAgKytjb3VudDsKICAgICAgICAgKytmaXJzdDsKICAgICAgfSBlbHNlIGlmICgqbmVlZGxlRmlyc3QgPCAqZmlyc3QpIHsKICAgICAgICAgKytuZWVkbGVGaXJzdDsKICAgICAgfSBlbHNlIHsKICAgICAgCSsrZmlyc3Q7CiAgICAgIH0KICAgfQogICAKICAgcmV0dXJuIGNvdW50Owp9CgoKaW50IG1haW4oKQp7CiAgICBpbnQgYXJyYXlGaXJzdFtdID0geyAxMSwgNSwgMiwgOCwgNCwgNSwgMiwgNSwgNywgOSwgMTIsIDE2LCAxNywgMTgsIDIwIH07CiAgICBpbnQgYXJyYXlTZWNvbmRbXSA9IHsgMjIsIDUsIDgsIDMsIDIsIDksIDQsIDMsIDksIDEwIH07CiAgICAKICAgIHN0ZDo6c29ydChzdGQ6OmJlZ2luKGFycmF5U2Vjb25kKSwgc3RkOjplbmQoYXJyYXlTZWNvbmQpKTsKICAgIGF1dG8gY29uc3QgYXJyYXlTZWNvbmRFbmQgPSBzdGQ6OnVuaXF1ZShzdGQ6OmJlZ2luKGFycmF5U2Vjb25kKSwgc3RkOjplbmQoYXJyYXlTZWNvbmQpKTsKICAgIAogICAgYXV0byBjb25zdCBudW1UaHJlYWRzID0gc3RkOjp0aHJlYWQ6OmhhcmR3YXJlX2NvbmN1cnJlbmN5KCk7CiAgICBzdGQ6OnZlY3RvcjxzdGQ6OnRocmVhZD4gdGFza3M7CiAgICB0YXNrcy5yZXNlcnZlKG51bVRocmVhZHMpOwogICAgc3RkOjp2ZWN0b3I8c2l6ZV90PiByZXN1bHRzKG51bVRocmVhZHMpOwogICAgCiAgICBhdXRvIGNvbnN0IGZpcnN0U2l6ZSAgPSBzaXplb2YoYXJyYXlGaXJzdCkgLyBzaXplb2YoKmFycmF5Rmlyc3QpOyAKICAgIGF1dG8gY29uc3QgZmlyc3RTdGVwID0gKGZpcnN0U2l6ZSArIG51bVRocmVhZHMgLSAxKSAvIG51bVRocmVhZHM7CiAgICAKICAgIGZvciAoc3RkOjpzaXplX3QgaSA9IDA7IGkgIT0gbnVtVGhyZWFkczsgKytpKSB7CiAgICAJYXV0byBjb25zdCBmaXJzdEJlZ2luID0gYXJyYXlGaXJzdCArIGkgKiBmaXJzdFN0ZXA7CiAgICAJYXV0byBjb25zdCBmaXJzdEVuZCAgID0gYXJyYXlGaXJzdCArIHN0ZDo6bWluKChpICsgMSkgKiBmaXJzdFN0ZXAsIGZpcnN0U2l6ZSk7CiAgICAJCiAgICAJc3RkOjp0aHJlYWQgdGFzayhbPSwgJnJlc3VsdHNdICgpIHsKICAgIAkJcmVzdWx0c1tpXSA9IGNvdW50X25lZWRsZShmaXJzdEJlZ2luLCBmaXJzdEVuZCwgYXJyYXlTZWNvbmQsIGFycmF5U2Vjb25kRW5kKTsKICAgIAl9KTsKICAgIAl0YXNrcy5wdXNoX2JhY2soc3RkOjptb3ZlKHRhc2spKTsKICAgIH0KICAgIAogICAgZm9yIChhdXRvICYgdGFzayA6IHRhc2tzKSB7CiAgICAgICB0YXNrLmpvaW4oKTsKICAgIH0KICAgIAogICAgYXV0byBjb25zdCBjb3VudCA9IHN0ZDo6YWNjdW11bGF0ZShzdGQ6OmJlZ2luKHJlc3VsdHMpLCBzdGQ6OmVuZChyZXN1bHRzKSwgc3RkOjpzaXplX3QoMCkpOwogICAgCiAgICBzdGQ6OmNvdXQgPDwgY291bnQgPDwgc3RkOjplbmRsOwp9