#include using namespace std; void rd(int &x){ int k, m=0; x=0; for(;;){ k = getchar_unlocked(); if(k=='-'){ m=1; break; } if('0'<=k&&k<='9'){ x=k-'0'; break; } } for(;;){ k = getchar_unlocked(); if(k<'0'||k>'9'){ break; } x=x*10+k-'0'; } if(m){ x=-x; } } void rd(long long &x){ int k, m=0; x=0; for(;;){ k = getchar_unlocked(); if(k=='-'){ m=1; break; } if('0'<=k&&k<='9'){ x=k-'0'; break; } } for(;;){ k = getchar_unlocked(); if(k<'0'||k>'9'){ break; } x=x*10+k-'0'; } if(m){ x=-x; } } int rd(char c[]){ int i, sz=0; for(;;){ i = getchar_unlocked(); if(i!=' '&&i!='\n'&&i!='\r'&&i!='\t'&&i!=EOF){ break; } } c[sz++] = i; for(;;){ i = getchar_unlocked(); if(i==' '||i=='\n'||i=='\r'||i=='\t'||i==EOF){ break; } c[sz++] = i; } c[sz]='\0'; return sz; } void wt_L(long long x){ char f[20]; int m=0, s=0; if(x<0){ m=1; x=-x; } while(x){ f[s++]=x%10; x/=10; } if(!s){ f[s++]=0; } if(m){ putchar_unlocked('-'); } while(s--){ putchar_unlocked(f[s]+'0'); } } char *S[100000], mem[1000100], memo[200000000]; int LCP[1000100], M, N, SA[1000100], *arr, ind[100000], len[100000], rSA[1000100]; long long d, x; void *wmem; template void SuffixArray(T *s, int N, int K, int *SA, int *LCP, void *mem){ char *lms, *t; int *cnt, *cnt1, *cnt2, d, i, j, m, name, pos, prev, *s1; t = (char*)mem; lms = t+N+1; cnt = (int*)(lms+N+1); cnt1 = cnt+K+1; cnt2 = cnt1+K+1; mem = cnt2+K+1; N++; s[N-1] = 0; t[N-1] = 1; t[N-2] = 0; for(i=N-3;i>=0;i--){ if(s[i] < s[i+1] || (s[i]==s[i+1] && t[i+1])){ t[i] = 1; } else{ t[i] = 0; } } lms[0] = 0; for(i=1;i=0 && !t[j]){ SA[cnt[s[j]]++] = j; } } for(i=0;i=0;i--){ j = SA[i] - 1; if(j>=0 && t[j]){ SA[--cnt[s[j]]] = j; } } m = 0; for(i=0;i0 && (lms[pos+d] || lms[prev+d])){ break; } } pos /= 2; SA[m+pos]=name-1; } for(i=N-1, j=N-1; i>=m; i--){ if(SA[i]>=0){ SA[j--]=SA[i]; } } s1 = SA+N-m; if(name=0; i--){ j=SA[i]; SA[i]=-1; SA[--cnt[s[j]]]=j; } for(i=0;i=0 && !t[j]){ SA[cnt2[s[j]]++] = j; } } for(i=N-1;i>=0;i--){ j = SA[i] - 1; if(j>=0 && t[j]){ SA[--cnt1[s[j]]] = j; } } if(LCP != NULL){ cnt = (int*)t; d = 0; for(i=0;i0){ d--; } } } } template void doublingRMQBuild(T arr[], int n, int res[]){ int hf, i, k; for(i=0;i= n){ break; } for(i=0;i arr[res[n*(k-1)+i+hf]]){ res[n*k+i] = res[n*(k-1)+i+hf]; } } } } template void* doublingRMQBuild(T arr[], int n, int **res, void *workMemory){ int hf, i, k; *res = (int*)workMemory; for(i=0;i= n){ break; } for(i=0;i arr[(*res)[n*(k-1)+i+hf]]){ (*res)[n*k+i] = (*res)[n*(k-1)+i+hf]; } } } return (void*)((*res)+n*k); } template int doublingRMQQuery(T arr[], int n, int rmq[], int a, int b){ int A, B, dep, wid=b-a+1; for(dep=0;(1<<(dep+1))<=wid;dep++){ ; } A = rmq[n*dep+a]; B = rmq[n*dep+b-(1< arr[B]){ A = B; } return A; } int main(){ int i, j, k, m, mx, s=0, xx, yy; long long fx, res=0; wmem = memo; rd(N); for(i=0;i j){ swap(i,j); } else{ j++; } x += d; if(x >= (long long)N * (N-1)){ x -= (long long)N * (N-1); } xx = rSA[ind[i]]; yy = rSA[ind[j]]; if(xx > yy){ swap(xx, yy); } mx = LCP[doublingRMQQuery(LCP, s+1, arr, xx+1, yy)]; res += mx; } wt_L(res); putchar_unlocked('\n'); return 0; } // cLay varsion 20170505-3 // --- original code --- // template // void SuffixArray(T *s, int N, int K, int *SA, int *LCP, void *mem) { // int i, j, d, m, *s1; // int name, prev, pos; // char *t, *lms; // int *cnt, *cnt1, *cnt2; // // t = (char*)mem; // lms = t+N+1; // cnt = (int*)(lms+N+1); // cnt1 = cnt+K+1; // cnt2 = cnt1+K+1; // // mem = cnt2+K+1; // N++; // // s[N-1] = 0; // // t[N-1] = 1; // t[N-2] = 0; // for(i=N-3;i>=0;i--){ // if(s[i] < s[i+1] || (s[i]==s[i+1] && t[i+1])) t[i] = 1; else t[i] = 0; // } // lms[0] = 0; // REP(i,1,N){ // if(t[i] && !t[i-1]) lms[i] = 1; else lms[i] = 0; // } // // rep(i,K+1) cnt1[i] = 0; // rep(i,N) cnt1[s[i]]++; // j = 0; // rep(i,K+1){ // j += cnt1[i]; // cnt2[i] = j - cnt1[i]; // cnt1[i] = j; // } // // rep(i,K+1) cnt[i] = cnt1[i]; // for(i=0; i=0 && !t[j]) SA[cnt[s[j]]++] = j; // } // // rep(i,K+1) cnt[i] = cnt1[i]; // for(i=N-1;i>=0;i--){ // j = SA[i] - 1; // if(j>=0 && t[j]) SA[--cnt[s[j]]] = j; // } // // m = 0; // rep(i,N) if(lms[SA[i]]) SA[m++] = SA[i]; // REP(i,m,N) SA[i] = -1; // // name=0; // prev=-1; // rep(i,m){ // pos = SA[i]; // rep(d,N){ // if(prev==-1 || s[pos+d]!=s[prev+d] || t[pos+d]!=t[prev+d]){ // name++; // prev=pos; // break; // } else if(d>0 && (lms[pos+d] || lms[prev+d])){ // break; // } // } // pos /= 2; // SA[m+pos]=name-1; // } // for(i=N-1, j=N-1; i>=m; i--) if(SA[i]>=0) SA[j--]=SA[i]; // // s1 = SA+N-m; // if(name=0; i--) { // j=SA[i]; SA[i]=-1; // SA[--cnt[s[j]]]=j; // } // // rep(i,N){ // j = SA[i]-1; // if(j>=0 && !t[j]) SA[cnt2[s[j]]++] = j; // } // // for(i=N-1;i>=0;i--){ // j = SA[i] - 1; // if(j>=0 && t[j]) SA[--cnt1[s[j]]] = j; // } // // if(LCP != NULL){ // cnt = (int*)t; // d = 0; // rep(i,N) cnt[SA[i]] = i; // rep(i,N){ // if(cnt[i]){ // for(j=SA[cnt[i]-1]; j+d0) d--; // } // } // } // // // template // void doublingRMQBuild(T arr[], int n, int res[]){ // int i, k, hf; // // rep(i,n) res[i] = i; // for(k=1;;k++){ // hf = (1<<(k-1)); if(hf >= n) break; // rep(i,n){ // res[n*k+i] = res[n*(k-1)+i]; // if(i+hf < n && arr[res[n*k+i]] > arr[res[n*(k-1)+i+hf]]) res[n*k+i] = res[n*(k-1)+i+hf]; // } // } // } // // template // void* doublingRMQBuild(T arr[], int n, int **res, void *workMemory){ // int i, k, hf; // // *res = (int*)workMemory; // rep(i,n) (*res)[i] = i; // for(k=1;;k++){ // hf = (1<<(k-1)); if(hf >= n) break; // rep(i,n){ // (*res)[n*k+i] = (*res)[n*(k-1)+i]; // if(i+hf < n && arr[(*res)[n*k+i]] > arr[(*res)[n*(k-1)+i+hf]]) (*res)[n*k+i] = (*res)[n*(k-1)+i+hf]; // } // } // // return (void*)((*res)+n*k); // } // template // int doublingRMQQuery(T arr[], int n, int rmq[], int a, int b){ // int dep, wid = b-a+1, A, B; // for(dep=0;(1<<(dep+1))<=wid;dep++); // A = rmq[n*dep+a]; // B = rmq[n*dep+b-(1< arr[B]) A = B; // return A; // } // // int N; // char *S[100000], mem[1000100]; // int len[100000], ind[100000]; // int M; ll x, d; // // int SA[1000100], LCP[1000100], rSA[1000100]; // int *arr; // // void *wmem; // char memo[200000000]; // // { // int i, j, k, m, mx, s = 0; // int xx, yy; // ll fx; // ll res = 0; // // wmem = memo; // // rd(N); // rep(i,N){ // S[i] = mem+s; // ind[i] = s; // rd(&mem[s]@len[i]); // s += len[i]; // } // // SuffixArray(S[0], s, 128, SA, LCP, wmem); // wmem = doublingRMQBuild(LCP, s+1, &arr, wmem); // // rep(i,s+1) rSA[SA[i]] = i; // // rd(M,x,d); // fx = x; // rep(k,M){ // i = x / (N-1); // j = x % (N-1); // if(i > j) swap(i,j); else j++; // // x += d; // if(x >= (ll)N * (N-1)) x -= (ll)N * (N-1); // // xx = rSA[ind[i]]; // yy = rSA[ind[j]]; // if(xx > yy) swap(xx, yy); // mx = LCP[doublingRMQQuery(LCP, s+1, arr, xx+1, yy)]; // res += mx; // } // // wt(res); // }