#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()
{
for(int N = 100; N <= 100000000; N *= 10)
{
vector<int> a;
vector<short> b;
for(int i = 0; i < N; ++i)
{
a.push_back( 1 );
if (i&1)
b.push_back(1);
}
b.push_back(0);
auto start = clock();
cout << "N : " << N << endl;
cout << (search(a.begin(),a.end(),b.begin(),b.end()) != a.end()) << endl;
auto stop = clock();
auto rand_time = stop - start;
cout << "search: " << rand_time << endl;
start = clock();
cout << find(a,b) << endl;
stop = clock();
rand_time = stop - start;
cout << "find : " << rand_time << endl << endl;
}
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPHJhbmRvbT4KI2luY2x1ZGUgPGNocm9ubz4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0eXBlZGVmIHVuc2lnbmVkIGxvbmcgbG9uZyB1bGw7CnR5cGVkZWYgcGFpcjx1bGwsdWxsPiBwbGw7Cgpjb25zdCB1bGwgYmFzZSA9IDMxOwpjb25zdCBwbGwgbW9kID0gcGxsKDEwMDAwMDAwMDAxMywxMDAwMDAwMDAwMDA5KTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgp2b2lkIG1vZGlmKHBsbCYgdmFsdWUsIFQgYWRkKXsKICAgIHZhbHVlID0gcGxsKCAodmFsdWUuZmlyc3QgKiBiYXNlICsgYWRkKSAlIG1vZC5maXJzdCwgKHZhbHVlLnNlY29uZCogYmFzZSArIGFkZCkgJSBtb2Quc2Vjb25kKTsKfQoKdGVtcGxhdGUgPCB0eXBlbmFtZSBMZWZ0T3BlcmFuZCwgdHlwZW5hbWUgUmlndGhPcGVyYW5kID4KTGVmdE9wZXJhbmQgKiBmaW5kKHZlY3RvcjxMZWZ0T3BlcmFuZD4mIGxlZnQsIHZlY3RvcjxSaWd0aE9wZXJhbmQ+JiByaWd0aCl7CiAgICAgaWYgKHJpZ3RoLnNpemUoKSA+IGxlZnQuc2l6ZSgpKQogICAgICAgIHJldHVybiBudWxscHRyOwoKICAgICBwbGwgcG93TW9kID0gcGxsKDEsMSk7CiAgICAgcGxsIGN1cnJlbnRMZWZ0ID0gcGxsKDAsMCk7CiAgICAgcGxsIHZhbHVlUmlndGggPSBwbGwoMCwwKTsKCiAgICAgZm9yIChzaXplX3QgaSA9MDsgaSA8IHJpZ3RoLnNpemUoKTsgaSsrICkgewogICAgICAgICAgbW9kaWYocG93TW9kLDApOwogICAgICAgICAgbW9kaWYoY3VycmVudExlZnQsIGxlZnRbaV0pOwogICAgICAgICAgbW9kaWYodmFsdWVSaWd0aCwgcmlndGhbaV0pOwogICAgIH0KICAgICBmb3IgKHNpemVfdCBMID0gMCwgUiA9IHJpZ3RoLnNpemUoKTsgO0wrKyxSKyspewogICAgICAgICAgICBpZiAoY3VycmVudExlZnQgPT0gdmFsdWVSaWd0aCkKICAgICAgICAgICAgICAgIHJldHVybiAmbGVmdFtMXTsKICAgICAgICAgICAgaWYgKFIgPT0gbGVmdC5zaXplKCkpCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbHB0cjsKICAgICAgICAgICAgbW9kaWYoY3VycmVudExlZnQsIGxlZnRbUl0pOwogICAgICAgICAgICBjdXJyZW50TGVmdCA9IHBsbCgKICAgICAgICAgICAgICAgIChjdXJyZW50TGVmdC5maXJzdCAtIGxlZnRbTF0qcG93TW9kLmZpcnN0ICUgbW9kLmZpcnN0ICkgJSBtb2QuZmlyc3QsCiAgICAgICAgICAgICAgICAoY3VycmVudExlZnQuc2Vjb25kLSBsZWZ0W0xdKnBvd01vZC5zZWNvbmQlIG1vZC5zZWNvbmQpICUgbW9kLnNlY29uZAogICAgICAgICAgICApOwogICAgIH0KfQoKaW50IG1haW4oKQp7CgogICAgZm9yKGludCBOID0gMTAwOyBOIDw9IDEwMDAwMDAwMDsgTiAqPSAxMCkKICAgIHsKICAgICAgICB2ZWN0b3I8aW50PiAgIGE7CiAgICAgICAgdmVjdG9yPHNob3J0PiBiOwoKICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgTjsgKytpKQogICAgICAgIHsKICAgICAgICAgICAgYS5wdXNoX2JhY2soIDEgKTsKICAgICAgICAgICAgaWYgKGkmMSkKICAgICAgICAgICAgICAgIGIucHVzaF9iYWNrKDEpOwogICAgICAgIH0KICAgICAgICBiLnB1c2hfYmFjaygwKTsKCiAgICAgICAgYXV0byBzdGFydCA9IGNsb2NrKCk7CiAgICAgICAgY291dCA8PCAiTiA6ICIgPDwgTiA8PCBlbmRsOwogICAgICAgIGNvdXQgPDwgKHNlYXJjaChhLmJlZ2luKCksYS5lbmQoKSxiLmJlZ2luKCksYi5lbmQoKSkgIT0gYS5lbmQoKSkgPDwgZW5kbDsKICAgICAgICBhdXRvIHN0b3AgPSBjbG9jaygpOwogICAgICAgIGF1dG8gcmFuZF90aW1lID0gc3RvcCAtIHN0YXJ0OwogICAgICAgIGNvdXQgPDwgInNlYXJjaDogIiA8PCByYW5kX3RpbWUgPDwgZW5kbDsKICAgICAgICBzdGFydCA9IGNsb2NrKCk7CgogICAgICAgIGNvdXQgPDwgZmluZChhLGIpIDw8IGVuZGw7CiAgICAgICAgc3RvcCA9IGNsb2NrKCk7CiAgICAgICAgcmFuZF90aW1lID0gc3RvcCAtIHN0YXJ0OwogICAgICAgIGNvdXQgPDwgImZpbmQgIDogIiA8PCByYW5kX3RpbWUgPDwgZW5kbCA8PCBlbmRsOwogICAgfQoKfQo=