結果
問題 | No.515 典型LCP |
ユーザー | LayCurse |
提出日時 | 2017-05-06 03:12:04 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 686 ms / 1,000 ms |
コード長 | 10,391 bytes |
コンパイル時間 | 2,514 ms |
コンパイル使用メモリ | 167,084 KB |
実行使用メモリ | 83,968 KB |
最終ジャッジ日時 | 2024-09-14 12:07:53 |
合計ジャッジ時間 | 7,827 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge6 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 686 ms
83,968 KB |
testcase_01 | AC | 428 ms
83,968 KB |
testcase_02 | AC | 199 ms
82,304 KB |
testcase_03 | AC | 1 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 237 ms
82,432 KB |
testcase_06 | AC | 250 ms
82,432 KB |
testcase_07 | AC | 241 ms
82,304 KB |
testcase_08 | AC | 264 ms
82,432 KB |
testcase_09 | AC | 144 ms
82,432 KB |
testcase_10 | AC | 149 ms
82,304 KB |
testcase_11 | AC | 143 ms
82,432 KB |
testcase_12 | AC | 146 ms
82,304 KB |
testcase_13 | AC | 143 ms
82,304 KB |
testcase_14 | AC | 86 ms
82,432 KB |
testcase_15 | AC | 219 ms
82,432 KB |
testcase_16 | AC | 221 ms
82,432 KB |
ソースコード
#include<bits/stdc++.h> 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'); } } template<class S, class T> inline S min_L(S a,T b){ return a<=b?a:b; } char *S[100000], mem[1000100], memo[200000000]; int LCP[1000100], M, N, SA[1000100], *arr, dodep[1000010], ind[100000], len[100000], rSA[1000100]; long long d, x; void *wmem; template<class T> 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<N;i++){ if(t[i] && !t[i-1]){ lms[i] = 1; } else{ lms[i] = 0; } } for(i=0;i<K+1;i++){ cnt1[i] = 0; } for(i=0;i<N;i++){ cnt1[s[i]]++; } j = 0; for(i=0;i<K+1;i++){ j += cnt1[i]; cnt2[i] = j - cnt1[i]; cnt1[i] = j; } for(i=0;i<K+1;i++){ cnt[i] = cnt1[i]; } for(i=0; i<N; i++){ SA[i] = -1; } for(i=1; i<N; i++){ if(lms[i]){ SA[--cnt[s[i]]]=i; } } for(i=0;i<K+1;i++){ cnt[i] = cnt2[i]; } for(i=0;i<N;i++){ j = SA[i]-1; if(j>=0 && !t[j]){ SA[cnt[s[j]]++] = j; } } for(i=0;i<K+1;i++){ 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; for(i=0;i<N;i++){ if(lms[SA[i]]){ SA[m++] = SA[i]; } } for(i=m;i<N;i++){ SA[i] = -1; } name=0; prev=-1; for(i=0;i<m;i++){ pos = SA[i]; for(d=0;d<N;d++){ 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<m){ SuffixArray(s1, m-1, name-1, SA, NULL, mem); } else{ for(i=0; i<m; i++){ SA[s1[i]] = i; } } for(i=0;i<K+1;i++){ cnt[i] = cnt1[i]; } for(i=1, j=0; i<N; i++){ if(lms[i]){ s1[j++]=i; } } for(i=0; i<m; i++){ SA[i]=s1[SA[i]]; } for(i=m; i<N; i++){ SA[i]=-1; } for(i=m-1; i>=0; i--){ j=SA[i]; SA[i]=-1; SA[--cnt[s[j]]]=j; } for(i=0;i<N;i++){ 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; for(i=0;i<N;i++){ cnt[SA[i]] = i; } for(i=0;i<N;i++){ if(cnt[i]){ for(j=SA[cnt[i]-1]; j+d<N-1&&i+d<N-1&&s[j+d]==s[i+d];d++){ ; } LCP[cnt[i]]=d; } else{ LCP[cnt[i]] = -1; } if(d>0){ d--; } } } } template<class T> void* doublingRMQBuild(T arr[], int n, int **res, void *workMemory){ int hf, i, j, k; *res = (int*)workMemory; for(i=0;i<n;i++){ (*res)[i] = i; } for(k=1;;k++){ hf = (1<<(k-1)); if(hf >= n){ break; } for(i=0;i<n;i++){ (*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]; } } } j = 0; for(i=0;i<n;i++){ if(i==(1<<(j+1))){ j++; } dodep[i] = j; } return (void*)((*res)+n*k); } template<class T> int doublingRMQQuery(T arr[], int n, int rmq[], int a, int b){ int A, B, dep, wid=b-a+1; dep = dodep[wid]; A = rmq[n*dep+a]; B = rmq[n*dep+b-(1<<dep)+1]; if(arr[A] > 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<N;i++){ S[i] = mem+s; ind[i] = s; len[i] = rd(&mem[s]); s += len[i]; } SuffixArray(S[0], s, 128, SA, LCP, wmem); wmem = doublingRMQBuild(LCP, s+1, &arr, wmem); for(i=0;i<s+1;i++){ rSA[SA[i]] = i; } rd(M); rd(x); rd(d); fx = x; for(k=0;k<M;k++){ i = x / (N-1); j = x % (N-1); if(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)]; mx =min_L(min_L(mx, len[i]), len[j]); res += mx; } wt_L(res); putchar_unlocked('\n'); return 0; } // cLay varsion 20170505-3 // --- original code --- // template<class T> // 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<N; i++) SA[i] = -1; // for(i=1; i<N; i++) if(lms[i]) SA[--cnt[s[i]]]=i; // // rep(i,K+1) cnt[i] = cnt2[i]; // rep(i,N){ // j = SA[i]-1; // if(j>=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<m){ // SuffixArray(s1, m-1, name-1, SA, NULL, mem); // } else { // for(i=0; i<m; i++) SA[s1[i]] = i; // } // // rep(i,K+1) cnt[i] = cnt1[i]; // // for(i=1, j=0; i<N; i++) if(lms[i]) s1[j++]=i; // for(i=0; i<m; i++) SA[i]=s1[SA[i]]; // for(i=m; i<N; i++) SA[i]=-1; // for(i=m-1; i>=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+d<N-1&&i+d<N-1&&s[j+d]==s[i+d];d++); // LCP[cnt[i]]=d; // } else { // LCP[cnt[i]] = -1; // } // if(d>0) d--; // } // } // } // // // // int dodep[1000010]; // template<class T> // void* doublingRMQBuild(T arr[], int n, int **res, void *workMemory){ // int i, j, 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]; // } // } // // j = 0; // rep(i,n){ // if(i==(1<<(j+1))) j++; // dodep[i] = j; // } // return (void*)((*res)+n*k); // } // // template<class T> // int doublingRMQQuery(T arr[], int n, int rmq[], int a, int b){ // int dep, wid = b-a+1, A, B; // dep = dodep[wid]; // A = rmq[n*dep+a]; // B = rmq[n*dep+b-(1<<dep)+1]; // if(arr[A] > 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)]; // mx = min(mx, len[i], len[j]); // res += mx; // } // // wt(res); // }