CSES - TCR Contest - Results
Submission details
Task:Substrings
Sender:Hannes Ihalainen
Submission time:2017-11-21 18:08:12 +0200
Language:C++
Status:READY
Result:ACCEPTED
Test results
testverdicttime
#1ACCEPTED0.20 sdetails
#2ACCEPTED0.21 sdetails
#3ACCEPTED0.21 sdetails
#4ACCEPTED0.20 sdetails

Compiler report

input/code.cpp: In function 'int main()':
input/code.cpp:64:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int i=0; i<s.size(); ++i)k.push_back(s[i]-'@');
                          ^
input/code.cpp:67:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int i=0; i<s.size(); ++i){
                          ^
input/code.cpp:72:29: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int ii=2; ii<st.size(); ++ii){
                             ^

Code

#include <bits/stdc++.h>
#define MP make_pair
using namespace std;
string s;

long long hsh[101010];
long long ak[101010];
// long long A=999999937;
long long A=37;
long long B=1000000007;


inline long long ghsh(int p, int l){
  return (hsh[p+l]-((ak[l]*hsh[p])%B)+B)%B;
}


inline int lcp(int a, int b){
  int l=0;
  int r=s.size()-(max(a, b))-1;
  while (l<r){
    int m=(l+r+1)/2; 
    if (ghsh(a, m)==ghsh(b, m)) l=m;
    else r=m-1;
  }
  return l;
}

vector<int> suffixArray(vector<int> s, int S){
  int n=s.size(); int N=n+S;
  vector<int> sa(n), ra(n);
  for (int i=0; i<n; ++i) { sa[i]=i; ra[i]=s[i];}
  for (int k=0; k<n; k?k*=2:k++){
    vector<int> nsa(sa), nra(n), cnt(N);
    for (int i=0; i<n; ++i) nsa[i]=(nsa[i]-k+n)%n;
    for (int i=0; i<n; ++i) cnt[ra[i]]++;
    for (int i=1; i<N; ++i) cnt[i]+=cnt[i-1];
    for (int i=n-1; i>=0; --i) sa[--cnt[ra[nsa[i]]]]=nsa[i];
    int r=0;
    for (int i=1; i<n; ++i){
      if (ra[sa[i]]!=ra[sa[i-1]]) ++r;
      else if (ra[(sa[i]+k)%n]!=ra[(sa[i-1]+k)%n]) ++r;
      nra[sa[i]]=r;
    }
    ra=nra;
  }
  return sa;
}

bool cmp(const int& a, const int& b){
  int c=lcp(a, b);
  return s[a+c]<s[b+c];
}

vector<int> st;

int main(){
  ak[0]=1; for (int i=1; i<101010; ++i) ak[i]=ak[i-1]*A%B;
  ios_base::sync_with_stdio(0); cin.tie(0);
  cin >> s;
  s.push_back('@');
  
  vector<int> k;
  for (int i=0; i<s.size(); ++i)k.push_back(s[i]-'@');
  st=suffixArray(k, 30);
  
  for (int i=0; i<s.size(); ++i){
    hsh[i+1]=(hsh[i]*A+s[i])%B;
  }
  long long ans=0;
  ans=s.size()-st[1]-1;
  for (int ii=2; ii<st.size(); ++ii){
    int j=st[ii-1];
    int i=st[ii];
    int c=lcp(i, j);
    ans+=s.size()-i-1-c;
  }
  cout << ans << "\n";
}

Test details

Test 1

Verdict: ACCEPTED

input
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...

correct output
100000

user output
100000

Test 2

Verdict: ACCEPTED

input
BBABAABABBBAAAABAAABBBBBAABBAB...

correct output
4998501161

user output
4998501161

Test 3

Verdict: ACCEPTED

input
DCBBABDCCCDACABDBBDCDBCBBCAAAC...

correct output
4999300351

user output
4999300351

Test 4

Verdict: ACCEPTED

input
RSCJOOIABPKYDZMZPBCIXNWOSNRWYQ...

correct output
4999757536

user output
4999757536