結果
問題 | No.515 典型LCP |
ユーザー | btk |
提出日時 | 2017-05-05 23:21:46 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
RE
|
実行時間 | - |
コード長 | 4,180 bytes |
コンパイル時間 | 1,783 ms |
コンパイル使用メモリ | 174,828 KB |
実行使用メモリ | 11,136 KB |
最終ジャッジ日時 | 2024-09-14 09:11:18 |
合計ジャッジ時間 | 6,241 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | RE | - |
testcase_01 | RE | - |
testcase_02 | RE | - |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | RE | - |
testcase_06 | RE | - |
testcase_07 | RE | - |
testcase_08 | RE | - |
testcase_09 | RE | - |
testcase_10 | RE | - |
testcase_11 | RE | - |
testcase_12 | RE | - |
testcase_13 | RE | - |
testcase_14 | RE | - |
testcase_15 | RE | - |
testcase_16 | RE | - |
ソースコード
#include<bits/stdc++.h> using namespace std; typedef long long LL; #define fin "\n" #define FOR(i,bg,ed) for(int i=(bg);i<(ed);i++) #define REP(i,n) FOR(i,0,n) #define ALL(v) (v).begin(),(v).end() #define fi first #define se second #define pb push_back #define DEBUG if(0) #define REC(ret, ...) std::function<ret (__VA_ARGS__)> template <typename T>inline bool chmin(T &l,T r) {bool a=l>r;if(a)l=r;return a;} template <typename T>inline bool chmax(T &l,T r) {bool a=l<r;if(a)l=r;return a;} template <typename T> istream& operator>>(istream &is,vector<T> &v){ for(auto &it:v)is>>it; return is; } /* sa[0]=n //空文字列 lcp[i]:=suffix[sa[i]]とsuffix[sa[i+1]]の共通高さ */ namespace SA { int n, k; int R[500000]; int T[500000]; bool compare_sa(int i, int j) { if (R[i] != R[j])return R[i] < R[j]; else { int ri = i + k <= n ? R[i + k] : -1; int rj = j + k <= n ? R[j + k] : -1; return ri < rj; } } vector<int> construct_sa(string& S) { n = S.size(); vector<int> sa(n + 1); for (int i = 0; i <= n; i++) { sa[i] = i; R[i] = i < n ? S[i] : -1; } for (k = 1; k <= n; k *= 2) { sort(sa.begin(), sa.end(), compare_sa); T[sa[0]] = 0; for (int i = 1; i <= n; i++) T[sa[i]] = T[sa[i - 1]] + (compare_sa(sa[i - 1], sa[i]) ? 1 : 0); for (int i = 0; i <= n; i++) R[i] = T[i]; } return sa; } vector<int> construct_lcp(string& S, vector<int> &sa) { n = S.size(); for (int i = 0; i <= n; i++)R[sa[i]] = i; int h = 0; vector<int> lcp(n + 1, 0); for (int i = 0; i < n; i++) { int j = sa[R[i] - 1]; if (h > 0)h--; for (; j + h < n&&i + h < n; h++) { if (S[j + h] != S[i + h])break; } lcp[R[i] - 1] = h; } return lcp; } } namespace TABLE{ #define SIZE 3000000 int mem[2][SIZE]; //#defube CNT 100 //int cnt=0; //int mems[CNT][SIZE]; }; template <typename T> class min_sparse_table{ private: T *L,*R;int _size; void build(){ for(int k = _size,b=1 ;b*2<=_size; k+=_size,b<<=1) for(int i = 0; i < _size; i++){ if(i+b*2<=_size) L[k+i]=min(L[k-_size+i],L[k-_size+i+b]); if(i-b*2>=-1) R[k+i]=min(R[k-_size+i],R[k-_size+i-b]); } } public:/*methods*/ int size(){return _size;} T get(int l,int r){ int k=(31-__builtin_clz(r-l+1))*_size; return min(L[k+l],R[k+r]); } min_sparse_table(std::vector<T> &v) :L(TABLE::mem[0]),R(TABLE::mem[1]){ _size=v.size(); for(int i = 0; i < _size; i++)L[i]=R[i]=v[i]; build(); } min_sparse_table(T* v,int n) :L(TABLE::mem[0]),R(TABLE::mem[1]){ _size=n; for(int i = 0; i < _size; i++)L[i]=R[i]=v[i]; build(); } }; char s[900000]; int main(){ int N; scanf("%d",&N); char *ss=s; vector<int> id(N+1); int len=0; REP(i,N){ scanf("%s",ss); id[i]=len; while(*ss !='\0'){ ss++;len++; } *(ss++)='$';len++; } id.back()=len; *(ss++)='\0'; string str=s; LL x,d,M; scanf("%lld %lld %lld",&M,&x,&d); auto sa = SA::construct_sa(str); auto cww=sa; REP(i,sa.size()){ cww[sa[i]]=i; } auto lcp = SA::construct_lcp(str,sa); min_sparse_table<int> rmq(lcp); LL res=0; REP(q,M){ LL i = x/(N-1)+1; LL j = x%(N-1)+1; if(i>j)swap(i,j); else j++; i--,j--; int ij=min(id[i+1]-id[i],id[j+1]-id[j])-1; i=cww[id[i]]; j=cww[id[j]]; if(i>j)swap(i,j); if(i==j){ res+=id[i+1]-id[i]-1; //cout<<"a"<<endl; } else { int k=rmq.get(i,j-1); res+=min(k,ij); //cout<<k<<endl; } x=(x+d)%(N*(N-1)); } printf("%lld\n",res); return 0; }