Cod sursa(job #2906308)

Utilizator vlad.ulmeanu30Ulmeanu Vlad vlad.ulmeanu30 Data 25 mai 2022 16:14:00
Problema Prefix Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.82 kb
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")

#include <bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define pll pair<ll,ll>
#define fi first
#define se second
#define inf (INT_MAX/2-1)
#define infl (1LL<<61)
#define vi vector<int>
#define vl vector<ll>
#define pb push_back
#define sz(a) ((int)(a).size())
#define all(a) begin(a),end(a)
#define y0 y5656
#define y1 y7878
#define aaa system("pause");
#define dbg(x) std::cerr<<(#x)<<": "<<(x)<<'\n',aaa
#define dbga(x,n) std::cerr<<(#x)<<"[]: ";for(int _=0;_<n;_++)std::cerr<<x[_]<<' ';std::cerr<<'\n',aaa
#define dbgs(x) std::cerr<<(#x)<<"[stl]: ";for(auto _:x)std::cerr<<_<<' ';std::cerr<<'\n',aaa
#define dbgp(x) std::cerr<<(#x)<<": "<<x.fi<<' '<<x.se<<'\n',aaa
#define dbgsp(x) std::cerr<<(#x)<<"[stl pair]:\n";for(auto _:x)std::cerr<<_.fi<<' '<<_.se<<'\n';aaa
#define maxn 1000000

using namespace std;

ifstream fin("prefix.in");
ofstream fout("prefix.out");

int lps[maxn+5];
const int mod = 1000000007;
int p27[maxn+5];

struct hasher {
  int n;
  string s;
  vi pref;

  hasher (string &s_, int n_) {
    s = s_;
    n = n_;
    assert(sz(s) == n+1); /// " " + ...

    pref.resize(n+1, 0);
    for (int i = 1; i <= n; i++) {
      pref[i] = ((ll)pref[i-1] * 27 + s[i] - 'a' + 1) % mod;
    }
  }


  ///hash pentru [l, r].
  int cut (int l, int r) {
    if (l > r) swap(l, r);

    assert(1 <= l);
    assert(r <= n);

    return (pref[r] - (ll)pref[l-1] * p27[r-l+1] % mod + mod) % mod;
  }
};

void solver() {
  string s; fin >> s;
  int n = sz(s);
  s = " " + s;

  int i, j, z;

  lps[0] = lps[1] = 0;
  for (i = 2; i <= n; i++) {
    if (s[lps[i-1]+1] == s[i]) {
      lps[i] = 1 + lps[i-1];
    } else {
      j = i;
      while (j > 0 && s[lps[j-1]+1] != s[i]) {
        j = lps[j-1];
      }

      if (j > 0) {
        lps[i] = lps[j-1] + 1;
      } else {
        lps[i] = 0;
      }
    }
  }

  ///pentru un prefix anume din string, ma folosesc de lps astfel:
  ///[-----==========].....
  ///.....[==========-----]
  ///pp ca [-] este cel mai lung prefix diferit de tot sirul csd curent care este si sufix.
  ///portiunea comuna este la fel, daca vr ca sirul curent sa fie concatenare de aceleasi prefixe, trb ca
  ///.. ramase in fata sa fie la fel ca .. ramase in spate, iar lps[x] * 2 >= x.

  hasher H(s, n);
  int ans = 0;

  for (i = n; i >= 1; i--) {
    if (2 * lps[i] >= i && H.cut(1, i-lps[i]) == H.cut(lps[i]+1, i)) {
      fout << i << '\n';
      return;
    }
  }

  fout << "0\n";
}

int main () {
  p27[0] = 1;
  for (int i = 1; i <= maxn; i++) {
    p27[i] = (ll)p27[i-1] * 27 % mod;
  }

  int t; fin >> t;
  while (t--) solver();

  fin.close();
  fout.close();

  return 0;
}