This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<iostream>
#include<stack>
#include<map>
#include<vector>
#include<string>
#include<unordered_map>
#include <queue>
#include<cstring>
#include<limits.h>
#include <cassert>
#include<cmath>
#include<set>
#include<algorithm>
#include <iomanip>
#include<numeric> //gcd(a,b)
#include<bitset>
#include <cstdlib>
#include <cstdint>
using namespace std;
#define ll long long
#define f first
//#define endl "\n"
#define s second
#define pii pair<int,int>
#define ppii pair<int,pii>
#define vi vector<int>
#define pb push_back
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define F(n) for(int i=0;i<n;i++)
#define lb lower_bound
#define ub upper_bound
#define fastio ios::sync_with_stdio(false);cin.tie(NULL);
#pragma GCC optimize ("03,unroll-loops")
using namespace std;
#define int long long
#define double long double
const int mod=1e9+7,mxn=4e3+5,lg=60,inf=1e18,minf=-1e18;
int base=101;
int p[mxn+10],invp[mxn+10],prefa[mxn+10],prefb[mxn+10];
string a,b;
int geta(int l,int r){
int x=prefa[r];
if(l){
x=(x-prefa[l-1]+mod)%mod;
x=(x*invp[l])%mod;
}
return x;
}
int getb(int l,int r){
int x=prefb[r];
if(l){
x=(x-prefb[l-1]+mod)%mod;
x=(x*invp[l])%mod;
}
return x;
}
int inv(int x){
int ex=mod-2,ans=1;
while(ex){
if(ex&1)ans=(ans*x)%mod;
x=(x*x)%mod;
ex>>=1;
}
return ans;
}
vector<int>posb[27],posa[27];
int mx[mxn+10];
vector<pii>have[mxn+10];
int get(int p1,int p2){
int l=0,r=min(a.size()-p1-1,b.size()-p2-1),ans=minf;
while(l<=r){
int mid=l+(r-l)/2;
if(geta(p1,p1+mid)==getb(p2,p2+mid))l=mid+1,ans=max(ans,mid);
else r=mid-1;
}
return ans;
}
struct fen{
int fwk[mxn+10];
void init(int n){for(int i=0;i<=n;i++)fwk[i]=inf;}
void update(int pos,int val){
pos=a.size()-pos;
for(int i=pos;i<=a.size();i+=(i&-i))fwk[i]=min(fwk[i],val);
}
int qry(int pos){
pos=a.size()-pos;
int ans=inf;
for(int i=pos;i>0;i-=(i&-i))ans=min(ans,fwk[i]);
return ans;
}
}g[mxn+10];
pair<int,pii>ans={0,{0,0}};
bool yes=0,yes2=0;
void solve(){
for(int i=0;i<27;i++)posb[i].clear();
for(int i=0;i<b.size();i++){
prefb[i]=(p[i]*b[i])%mod;
if(i)prefb[i]=(prefb[i]+prefb[i-1])%mod;
}
for(int i=0;i<b.size();i++)posb[b[i]-'a'].pb(i);
for(int i=0;i<b.size();i++)g[i].init(a.size());
for(int i=0;i<a.size();i++){
for(auto j:posb[a[i]-'a']){
int x=get(i,j);
g[j].update(i+x,i);//update
int k=j;
if(yes)k=(b.size()-1)-(j+x);
if(yes2)ans=max(ans,{x+1,{k,i}});
else ans=max(ans,{x+1,{i,k}});
if(j+x+1>=b.size())continue;
int y=g[j+x+1].qry(max(0LL,i-1));
if(y==inf)continue;
int l=i-y;
//cout<<i<<" "<<j<<' '<<y<<" "<<x<<' '<<l<<'\n';
if(yes)j=(b.size()-1)-(j+x+l);
if(yes2)ans=max(ans,{x+l+1,{j,y}});
else ans=max(ans,{x+l+1,{y,j}});
}
}
/*
find maxmatch
for(i ina)for(j inb){
pos2 ina where mxmatch(pos2,j+1mxmatch)>=curpos
and mxmatch is max
}
when we know j+1+mxmatch
we can have list of the matched matching with j{
range l,r;
want to find max(r-l) where l<=pos<=r
if we add inorder then all l<=pos
then we can only keep r
we can keep segtree and qry max on (pos,r)
}
*/
}
int32_t main(){
fastio
cin>>a>>b;
if(a.size()>b.size())swap(a,b),yes2=1;
int d=inv(base);
p[0]=invp[0]=1;
for(int i=1;i<max(a.size(),b.size());i++)p[i]=(p[i-1]*base)%mod,invp[i]=(invp[i-1]*d)%mod;
for(int i=0;i<a.size();i++){
prefa[i]=(p[i]*a[i])%mod;
if(i)prefa[i]=(prefa[i]+prefa[i-1])%mod;
}
solve();
reverse(all(b));
yes=1;
solve();
cout<<ans.f<<" "<<ans.s.f<<" "<<ans.s.s<<'\n';
}
/*
*/
Compilation message (stderr)
necklace.cpp: In member function 'void fen::update(long long int, long long int)':
necklace.cpp:84:18: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
84 | for(int i=pos;i<=a.size();i+=(i&-i))fwk[i]=min(fwk[i],val);
| ~^~~~~~~~~~
necklace.cpp: In function 'void solve()':
necklace.cpp:97:15: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
97 | for(int i=0;i<b.size();i++){
| ~^~~~~~~~~
necklace.cpp:101:15: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
101 | for(int i=0;i<b.size();i++)posb[b[i]-'a'].pb(i);
| ~^~~~~~~~~
necklace.cpp:102:15: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
102 | for(int i=0;i<b.size();i++)g[i].init(a.size());
| ~^~~~~~~~~
necklace.cpp:103:15: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
103 | for(int i=0;i<a.size();i++){
| ~^~~~~~~~~
necklace.cpp:111:12: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
111 | if(j+x+1>=b.size())continue;
| ~~~~~^~~~~~~~~~
necklace.cpp: In function 'int32_t main()':
necklace.cpp:143:15: warning: comparison of integer expressions of different signedness: 'long long int' and 'const long unsigned int' [-Wsign-compare]
143 | for(int i=1;i<max(a.size(),b.size());i++)p[i]=(p[i-1]*base)%mod,invp[i]=(invp[i-1]*d)%mod;
| ~^~~~~~~~~~~~~~~~~~~~~~~
necklace.cpp:144:15: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
144 | for(int i=0;i<a.size();i++){
| ~^~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |