Advertisement
NgJaBach

Double Hash (KMP problem)

Sep 20th, 2022
857
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.41 KB | None | 0 0
  1. // NgJaBach: Forever Meadow <3
  2.  
  3. #include<bits/stdc++.h>
  4.  
  5. using namespace std;
  6. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  7. typedef long long int ll;
  8. typedef unsigned long long ull;
  9. #define pb push_back
  10. #define pob pop_back
  11. #define mp make_pair
  12. #define upb upper_bound
  13. #define lwb lower_bound
  14. #define bend(a) a.begin(),a.end()
  15. #define rev(x) reverse(bend(x))
  16. #define mset(a) memset(a, 0, sizeof(a))
  17. #define fi first
  18. #define se second
  19. #define gcd __gcd
  20. #define getl(s) getline(cin, s);
  21. #define setpre(x) fixed << setprecision(x)
  22. #define endl '\n'
  23. const int N=10000050;
  24. const ll INF=1e18+7,base=311,M=1000000007,M2=1000000009;
  25. pair<ll,ll>operator-(pair<ll,ll>A,pair<ll,ll>B){
  26.     pair<ll,ll>C;
  27.     C.fi=A.fi-B.fi;
  28.     C.se=A.se-B.se;
  29.     return C;
  30. }
  31. pair<ll,ll>operator*(pair<ll,ll>A,pair<ll,ll> B){
  32.     pair<ll,ll>C;
  33.     C.fi=A.fi*B.fi;
  34.     C.se=A.se*B.se;
  35.     return C;
  36. }
  37. int n,m,ans,L,R,mid,pos;
  38. pair<ll,ll>double_bazooka[N],A,B,power[N];
  39. string s;
  40. int main(){
  41.     ios_base::sync_with_stdio(NULL); cin.tie(nullptr); cout.tie(nullptr);
  42. //    freopen("MR.inp","r",stdin);
  43. //    freopen("MR.out","w",stdout);
  44.     cin>>s;
  45.     m=s.size();
  46.     s+=s;
  47.     n=s.size();
  48.     power[0]={1,1};
  49.     for(int i=1;i<=n;++i) power[i]={(power[i-1].fi*base)%M,(power[i-1].se*base)%M2};
  50.     double_bazooka[0]={(s[0]-'a'+1)%M,(s[0]-'a'+1)%M2};
  51.     for(int i=1;i<n;++i) double_bazooka[i]={(double_bazooka[i-1].fi*base+s[i]-'a'+1)%M,(double_bazooka[i-1].se*base+s[i]-'a'+1)%M2};
  52.     ans=0;
  53.     for(int i=m;i<n;++i){
  54.         L=0; R=m-1;
  55.         pos=-1;
  56.         while(L<=R){
  57.             mid=(L+R)/2;
  58.             if(ans==0) A=double_bazooka[ans+mid];
  59.             else A=(double_bazooka[ans+mid]-double_bazooka[ans-1]*power[mid+1]);
  60.             A.fi=(A.fi+M*M)%M; A.se=(A.se+M2*M2)%M2;
  61.             B=(double_bazooka[i-m+1+mid]-double_bazooka[i-m]*power[mid+1]);
  62.             B.fi=(B.fi+M*M)%M; B.se=(B.se+M2*M2)%M2;
  63.             if(A!=B) R=mid-1;
  64.             else{
  65.                 L=mid+1;
  66.                 pos=max(pos,mid);
  67.             }
  68.         }
  69.         if((pos+1)==m) continue;
  70.         ++pos;
  71.         if(s[ans+pos]>s[i-m+1+pos]) ans=i-m+1;
  72.     }
  73.     for(int i=0;i<m;++i) cout<<s[ans+i];
  74.     return 0;
  75. }
  76. /*
  77. ==================================+
  78. INPUT:                            |
  79. ------------------------------    |
  80.  
  81. ------------------------------    |
  82. ==================================+
  83. OUTPUT:                           |
  84. ------------------------------    |
  85.  
  86. ------------------------------    |
  87. ==================================+
  88. */
  89.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement