#include <vector>
#include <string>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <random>
#include <chrono>
using namespace std;
typedef unsigned long long ull;
typedef pair<ull,ull> pll;
const ull base = 31;
const pll mod = pll(100000000013,1000000000009);
template <typename T>
void modif(pll& value, T add){
value = pll( (value.first * base + add) % mod.first, (value.second* base + add) % mod.second);
}
template < typename LeftOperand, typename RigthOperand >
LeftOperand * find(vector<LeftOperand>& left, vector<RigthOperand>& rigth){
if (rigth.size() > left.size())
return nullptr;
pll powMod = pll(1,1);
pll currentLeft = pll(0,0);
pll valueRigth = pll(0,0);
for (size_t i =0; i < rigth.size(); i++ ) {
modif(powMod,0);
modif(currentLeft, left[i]);
modif(valueRigth, rigth[i]);
}
for (size_t L = 0, R = rigth.size(); ;L++,R++){
if (currentLeft == valueRigth)
return &left[L];
if (R == left.size())
return nullptr;
modif(currentLeft, left[R]);
currentLeft = pll(
(currentLeft.first - left[L]*powMod.first % mod.first ) % mod.first,
(currentLeft.second- left[L]*powMod.second% mod.second) % mod.second
);
}
}
int main()
{
default_random_engine dre{random_device()()};
uniform_int_distribution<> uid(0,1000);
for(int N = 100; N <= 100000000; N *= 100)
{
vector<int> a;
vector<short> b;
for(int i = 0; i < N; ++i)
{
a.push_back(uid(dre));
if (N%10 == 0)
b.push_back(uid(dre));
}
auto start = chrono::high_resolution_clock::now();
cout << "N : " << N << " " <<(search(a.begin(),a.end(),b.begin(),b.end()) != a.end()) << endl;
auto stop = chrono::high_resolution_clock::now();
auto rand_time = stop - start;
cout << "search: " << chrono::duration_cast<chrono::nanoseconds>(stop-start).count() << endl;
start = chrono::high_resolution_clock::now();
cout << find(a,b) << endl;;
stop = chrono::high_resolution_clock::now();
rand_time = stop - start;
cout << "find : " << chrono::duration_cast<chrono::nanoseconds>(stop-start).count() << endl << endl;
}
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPHJhbmRvbT4KI2luY2x1ZGUgPGNocm9ubz4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0eXBlZGVmIHVuc2lnbmVkIGxvbmcgbG9uZyB1bGw7CnR5cGVkZWYgcGFpcjx1bGwsdWxsPiBwbGw7Cgpjb25zdCB1bGwgYmFzZSA9IDMxOwpjb25zdCBwbGwgbW9kID0gcGxsKDEwMDAwMDAwMDAxMywxMDAwMDAwMDAwMDA5KTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgp2b2lkIG1vZGlmKHBsbCYgdmFsdWUsIFQgYWRkKXsKICAgIHZhbHVlID0gcGxsKCAodmFsdWUuZmlyc3QgKiBiYXNlICsgYWRkKSAlIG1vZC5maXJzdCwgKHZhbHVlLnNlY29uZCogYmFzZSArIGFkZCkgJSBtb2Quc2Vjb25kKTsKfQoKdGVtcGxhdGUgPCB0eXBlbmFtZSBMZWZ0T3BlcmFuZCwgdHlwZW5hbWUgUmlndGhPcGVyYW5kID4KTGVmdE9wZXJhbmQgKiBmaW5kKHZlY3RvcjxMZWZ0T3BlcmFuZD4mIGxlZnQsIHZlY3RvcjxSaWd0aE9wZXJhbmQ+JiByaWd0aCl7CiAgICAgaWYgKHJpZ3RoLnNpemUoKSA+IGxlZnQuc2l6ZSgpKQogICAgICAgIHJldHVybiBudWxscHRyOwoKICAgICBwbGwgcG93TW9kID0gcGxsKDEsMSk7CiAgICAgcGxsIGN1cnJlbnRMZWZ0ID0gcGxsKDAsMCk7CiAgICAgcGxsIHZhbHVlUmlndGggPSBwbGwoMCwwKTsKCiAgICAgZm9yIChzaXplX3QgaSA9MDsgaSA8IHJpZ3RoLnNpemUoKTsgaSsrICkgewogICAgICAgICAgbW9kaWYocG93TW9kLDApOwogICAgICAgICAgbW9kaWYoY3VycmVudExlZnQsIGxlZnRbaV0pOwogICAgICAgICAgbW9kaWYodmFsdWVSaWd0aCwgcmlndGhbaV0pOwogICAgIH0KICAgICBmb3IgKHNpemVfdCBMID0gMCwgUiA9IHJpZ3RoLnNpemUoKTsgO0wrKyxSKyspewogICAgICAgICAgICBpZiAoY3VycmVudExlZnQgPT0gdmFsdWVSaWd0aCkKICAgICAgICAgICAgICAgIHJldHVybiAmbGVmdFtMXTsKICAgICAgICAgICAgaWYgKFIgPT0gbGVmdC5zaXplKCkpCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbHB0cjsKICAgICAgICAgICAgbW9kaWYoY3VycmVudExlZnQsIGxlZnRbUl0pOwogICAgICAgICAgICBjdXJyZW50TGVmdCA9IHBsbCggCiAgICAgICAgICAgICAgICAoY3VycmVudExlZnQuZmlyc3QgLSBsZWZ0W0xdKnBvd01vZC5maXJzdCAlIG1vZC5maXJzdCApICUgbW9kLmZpcnN0LAogICAgICAgICAgICAgICAgKGN1cnJlbnRMZWZ0LnNlY29uZC0gbGVmdFtMXSpwb3dNb2Quc2Vjb25kJSBtb2Quc2Vjb25kKSAlIG1vZC5zZWNvbmQKICAgICAgICAgICAgKTsKICAgICB9Cn0KCmludCBtYWluKCkKewogICAgZGVmYXVsdF9yYW5kb21fZW5naW5lIGRyZXtyYW5kb21fZGV2aWNlKCkoKX07CiAgICB1bmlmb3JtX2ludF9kaXN0cmlidXRpb248PiB1aWQoMCwxMDAwKTsKCiAgICBmb3IoaW50IE4gPSAxMDA7IE4gPD0gMTAwMDAwMDAwOyBOICo9IDEwMCkKICAgIHsKICAgICAgICB2ZWN0b3I8aW50PiAgIGE7CiAgICAgICAgdmVjdG9yPHNob3J0PiBiOwoKICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgTjsgKytpKQogICAgICAgIHsKICAgICAgICAgICAgYS5wdXNoX2JhY2sodWlkKGRyZSkpOwogICAgICAgICAgICBpZiAoTiUxMCA9PSAwKQogICAgICAgICAgICAgICAgYi5wdXNoX2JhY2sodWlkKGRyZSkpOwogICAgICAgIH0KCiAgICAgICAgYXV0byBzdGFydCA9IGNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsKICAgICAgICBjb3V0IDw8ICJOIDogIiA8PCBOIDw8ICIgICIgPDwoc2VhcmNoKGEuYmVnaW4oKSxhLmVuZCgpLGIuYmVnaW4oKSxiLmVuZCgpKSAhPSBhLmVuZCgpKSA8PCBlbmRsOwogICAgICAgIGF1dG8gc3RvcCA9IGNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsKICAgICAgICBhdXRvIHJhbmRfdGltZSA9IHN0b3AgLSBzdGFydDsKICAgICAgICBjb3V0IDw8ICJzZWFyY2g6ICIgPDwgY2hyb25vOjpkdXJhdGlvbl9jYXN0PGNocm9ubzo6bmFub3NlY29uZHM+KHN0b3Atc3RhcnQpLmNvdW50KCkgPDwgZW5kbDsKICAgICAgICBzdGFydCA9IGNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsKICAgICAgICBjb3V0IDw8IGZpbmQoYSxiKSA8PCBlbmRsOzsKICAgICAgICBzdG9wID0gY2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpOwogICAgICAgIHJhbmRfdGltZSA9IHN0b3AgLSBzdGFydDsKICAgICAgICBjb3V0IDw8ICJmaW5kICA6ICIgPDwgY2hyb25vOjpkdXJhdGlvbl9jYXN0PGNocm9ubzo6bmFub3NlY29uZHM+KHN0b3Atc3RhcnQpLmNvdW50KCkgPDwgZW5kbCA8PCBlbmRsOwogICAgfQoKfQo=