#include <bits/stdc++.h>
#define int long long
using namespace std;
mt19937 rng;
int INF = 1LL<<60;
int p = 2071723;
int MOD = 1000000033;
std::chrono::steady_clock::time_point begin2 = std::chrono::steady_clock::now();
string a;
string b;
int n,m;
vector<int> hashes;
void compute_hash(string s) {
int n1 = s.size();
hashes.clear();
hashes=vector<int>(n1+1,0);
int ha = 0;
for (int i=0; i<n1; i++) {
ha += s[i]-'a';
ha *= p;
ha %= MOD;
hashes[i+1] = ha;
}
}
int exp(int p, int n) {
int ans=1;
int r = p;
for (int i=0; i<30; i++) {
if (n&(1<<i)) {
ans*=r;
ans%=MOD;
}
r*=r;
r%=MOD;
}
return ans;
}
int gethash(int l, int r) {
int h1 = hashes[l];
int h2 = hashes[r+1];
h1 *= exp(p,r-l+1);
h1%=MOD;
int dif = h2-h1;
dif%=MOD;
dif+=MOD;
dif%=MOD;
return dif;
}
bool check(int a, int b, int length) {
return gethash(a,a+length-1)==gethash(b,b+length-1);
}
bool verify(int i, int j, int length) {
//checks if i...i+length-1 in a = j...j+length-1 in b
return gethash(i,length-1)==gethash(n+j, length-1);
}
int cutoff;
vector<pair<int,int>> solve() {
compute_hash(a+b);
int ans = 0;
pair<int,int> xpos;
pair<int,int> ypos;
for (int trial=0; trial*ans<40000000; trial++) {
if (!(trial%1000)) {
std::chrono::steady_clock::time_point end2 = std::chrono::steady_clock::now();
int x = std::chrono::duration_cast<std::chrono::microseconds>(end2 - begin2).count();
if (x>cutoff) {
//cout <<x <<" " << cutoff <<" " << trial << " " << ans << endl;
return {{ans,ans},xpos,ypos};
}
}
int i,j;
i=rng()%n;
j=rng()%m;
if (a[i]!=b[j]) {
continue;
}
int l,r;
l=0;
r=0;
while (l+i>=0 && l+j>=0 && a[i+l]==b[j+l]) {
//cout << "doing " << i <<" " << l <<" " << a[i+l] <<" " << b[j+l] << endl;
l--;
}
l++;
while (r+i<=n-1 && r+j<=m-1 && a[i+r]==b[j+r]) {
r++;
}
r--;
int length = r-l+1;
int subans = length;
if (subans>ans) {
ans=subans;
xpos={i+l,i+l+length};
ypos={j+l,j+l+length};
}
if (subans<=ans/2) {
continue;
}
for (int blubber=1; blubber<=length; blubber++) { //add it on both sides
int la = i+r+1;
int ra = i+r+blubber;
int lb = j+l-blubber;
int rb = j+l-1;
if (!(0<=la && la<=n-1) || !(0<=lb && rb<=m-1)) {
break;
}
if (gethash(la,ra)==gethash(n+lb,n+rb)) {
int subans = blubber+length;
if (subans>ans) {
//cout << a <<" " << b <<" " << ans <<" " << i <<" " << j <<" " << blubber <<" " << subans << endl;
//cout << la <<" " << ra <<" " << lb <<" " << rb << endl;
ans=subans;
xpos = {i+l,ra};
ypos = {lb,j+r};
}
}
}
}
return {{ans,ans},xpos,ypos};
}
signed main() {
//freopen("input.txt","r", stdin);
//freopen("output.txt","w",stdout);
const std::clock_t c_start = std::clock();
auto t_start = std::chrono::high_resolution_clock::now();
cin >> a;
cin >> b;
n=a.size();
m=b.size();
vector<pair<int,int>> ans2;
vector<int> ans(3);
int TL = 1300000;
cutoff=TL/4;
ans2=solve();
ans[0] = ans2[0].first;
ans[1] = ans2[1].first;
ans[2] = ans2[2].first;
reverse(b.begin(), b.end());
cutoff=2*TL/4;
ans2 = solve();
if (ans2[0].first>ans[0]) {
ans[0] = ans2[0].first;
ans[1] = ans2[1].first;
ans[2] = m-ans2[2].second-1;
}
reverse(a.begin(), a.end());
cutoff=3*TL/4;
ans2 = solve();
if (ans2[0].first>ans[0]) {
ans[0] = ans2[0].first;
ans[1] = n-ans2[1].second-1;
ans[2] = m-ans2[2].second-1;
}
reverse(b.begin(), b.end());
cutoff=4*TL/4;
ans2 = solve();
if (ans2[0].first>ans[0]) {
ans[0] = ans2[0].first;
ans[1] = n-ans2[1].second-1;
ans[2] = ans2[2].first;
}
cout << ans[0] << endl;
cout << ans[1] <<" " << ans[2] << endl;
//want to store for each x and j, the smallest t such that match[x][t]+t = j
}
Compilation message
necklace.cpp: In function 'int main()':
necklace.cpp:136:24: warning: unused variable 'c_start' [-Wunused-variable]
136 | const std::clock_t c_start = std::clock();
| ^~~~~~~
necklace.cpp:137:10: warning: variable 't_start' set but not used [-Wunused-but-set-variable]
137 | auto t_start = std::chrono::high_resolution_clock::now();
| ^~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1289 ms |
412 KB |
Output is correct |
2 |
Correct |
1299 ms |
412 KB |
Output is correct |
3 |
Correct |
1300 ms |
420 KB |
Output is correct |
4 |
Correct |
1295 ms |
416 KB |
Output is correct |
5 |
Correct |
477 ms |
344 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1289 ms |
412 KB |
Output is correct |
2 |
Correct |
1299 ms |
412 KB |
Output is correct |
3 |
Correct |
1300 ms |
420 KB |
Output is correct |
4 |
Correct |
1295 ms |
416 KB |
Output is correct |
5 |
Correct |
477 ms |
344 KB |
Output is correct |
6 |
Correct |
1294 ms |
428 KB |
Output is correct |
7 |
Correct |
1298 ms |
348 KB |
Output is correct |
8 |
Correct |
1054 ms |
428 KB |
Output is correct |
9 |
Correct |
1289 ms |
432 KB |
Output is correct |
10 |
Correct |
84 ms |
440 KB |
Output is correct |
11 |
Correct |
108 ms |
344 KB |
Output is correct |
12 |
Correct |
1297 ms |
436 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1289 ms |
412 KB |
Output is correct |
2 |
Correct |
1299 ms |
412 KB |
Output is correct |
3 |
Correct |
1300 ms |
420 KB |
Output is correct |
4 |
Correct |
1295 ms |
416 KB |
Output is correct |
5 |
Correct |
477 ms |
344 KB |
Output is correct |
6 |
Correct |
1294 ms |
428 KB |
Output is correct |
7 |
Correct |
1298 ms |
348 KB |
Output is correct |
8 |
Correct |
1054 ms |
428 KB |
Output is correct |
9 |
Correct |
1289 ms |
432 KB |
Output is correct |
10 |
Correct |
84 ms |
440 KB |
Output is correct |
11 |
Correct |
108 ms |
344 KB |
Output is correct |
12 |
Correct |
1297 ms |
436 KB |
Output is correct |
13 |
Correct |
1317 ms |
500 KB |
Output is correct |
14 |
Correct |
1319 ms |
520 KB |
Output is correct |
15 |
Correct |
1302 ms |
344 KB |
Output is correct |
16 |
Correct |
1040 ms |
480 KB |
Output is correct |
17 |
Correct |
13 ms |
348 KB |
Output is correct |
18 |
Correct |
106 ms |
496 KB |
Output is correct |
19 |
Correct |
1311 ms |
480 KB |
Output is correct |
20 |
Partially correct |
1304 ms |
348 KB |
Output is partially correct |
21 |
Correct |
1309 ms |
348 KB |
Output is correct |