結果
問題 | No.515 典型LCP |
ユーザー | chocorusk |
提出日時 | 2019-10-27 14:34:36 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 5,716 bytes |
コンパイル時間 | 1,822 ms |
コンパイル使用メモリ | 134,784 KB |
実行使用メモリ | 46,188 KB |
最終ジャッジ日時 | 2024-09-14 21:02:32 |
合計ジャッジ時間 | 14,908 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | TLE | - |
testcase_01 | TLE | - |
testcase_02 | AC | 543 ms
39,832 KB |
testcase_03 | AC | 3 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 799 ms
45,496 KB |
testcase_06 | AC | 986 ms
45,488 KB |
testcase_07 | AC | 900 ms
45,364 KB |
testcase_08 | TLE | - |
testcase_09 | AC | 477 ms
39,796 KB |
testcase_10 | AC | 481 ms
39,836 KB |
testcase_11 | AC | 480 ms
39,816 KB |
testcase_12 | AC | 479 ms
39,716 KB |
testcase_13 | AC | 418 ms
39,808 KB |
testcase_14 | AC | 99 ms
39,624 KB |
testcase_15 | AC | 507 ms
45,368 KB |
testcase_16 | AC | 510 ms
45,616 KB |
ソースコード
#include <cstdio> #include <cstring> #include <iostream> #include <string> #include <cmath> #include <bitset> #include <vector> #include <map> #include <set> #include <queue> #include <deque> #include <algorithm> #include <complex> #include <unordered_map> #include <unordered_set> #include <random> #include <cassert> #include <fstream> #include <utility> #include <functional> #include <time.h> #include <stack> #define popcount __builtin_popcount using namespace std; typedef long long int ll; typedef pair<int, int> P; //https://judge.yosupo.jp/submission/877 #define MP make_pair #define fi first #define se second #define ALL(a) (a).begin(),(a).end() struct SuffixArray{ ll size; string s; vector<ll>data; SuffixArray(string S):size(S.size()),s(S){ s += '$'; vector<ll>input(s.size()); for(ll i=0;i<s.size();i++)input[i] = s[i]; data = induced_sort(input, 200); data.erase(data.begin()); } vector<ll> induced_sort(vector<ll>t, ll kind){ ll sz = t.size(); vector<bool>ls(sz);//trueはL型,falseはS型 for(ll i = sz-1;i>=0;i--){ if(i==sz-1)ls[i] = false; else{ if(t[i]!=t[i+1])ls[i] = (t[i] > t[i+1]); else ls[i] = ls[i+1]; } } vector<ll>cnt(kind); for(ll i=0;i<sz;i++)cnt[t[i]]++; vector<P>lr(kind,MP(-1,-1)); for(ll i=1;i<kind;i++){ if(cnt[i]==0)lr[i] = lr[i-1]; else lr[i] = make_pair(lr[i-1].se + 1, lr[i-1].se + cnt[i]); } vector<ll>lmsidx,ret(sz,-1); for(ll i=0;i<sz-1;i++){ if(ls[i]&&!ls[i+1]){ ret[lr[t[i+1]].fi+cnt[t[i+1]]-1]=i+1; cnt[t[i+1]]--; lmsidx.push_back(i+1); } } fill(ALL(cnt),0); for(ll i=0;i<sz;i++){ if(ret[i]>=1&&ls[ret[i]-1]){ ret[lr[t[ret[i]-1]].fi+cnt[t[ret[i]-1]]]=ret[i]-1; cnt[t[ret[i]-1]]++; if(i!=0&&!ls[ret[i]])ret[i]=-1; } } fill(ALL(cnt),0); for(ll i=sz-1;i>=1;i--){ if(ret[i]>=1&&!ls[ret[i]-1]){ ret[lr[t[ret[i]-1]].se-cnt[t[ret[i]-1]]]=ret[i]-1; cnt[t[ret[i]-1]]++; } } vector<ll>rev_lmsidx(sz,-1),lmsinput(lmsidx.size(),-1); for(ll i=0;i<lmsidx.size();i++)rev_lmsidx[lmsidx[i]] = i; ll kindnum=1; lmsinput[rev_lmsidx[ret[0]]] = 1; vector<ll>comp(t.begin()+ret[0],t.end()); for(ll i=1;i<sz;i++){ if(ret[i]>=1&&ls[ret[i]-1]&&!ls[ret[i]]){ vector<ll>tmp(t.begin()+ret[i],t.begin()+lmsidx[rev_lmsidx[ret[i]]+1]+1); if(comp != tmp){ kindnum++; comp = tmp; } lmsinput[rev_lmsidx[ret[i]]] = kindnum; } } vector<ll>output; if(kindnum==lmsidx.size()){ output.assign(kindnum,-1); for(ll i=0;i<lmsinput.size();i++)output[lmsinput[i]-1]=i; } else output = induced_sort(lmsinput,kindnum+1); fill(ALL(cnt),0), fill(ALL(ret),-1); for(ll i=output.size()-1;i>=0;i--){ ll tmp=lmsidx[output[i]]; ret[lr[t[tmp]].se - cnt[t[tmp]]]=tmp; cnt[t[tmp]]++; } fill(ALL(cnt),0); for(ll i=0;i<sz;i++){ if(ret[i]>=1&&ls[ret[i]-1]){ ret[lr[t[ret[i]-1]].fi+cnt[t[ret[i]-1]]]=ret[i]-1; cnt[t[ret[i]-1]]++; if(i!=0&&!ls[ret[i]])ret[i]=-1; } } fill(ALL(cnt),0); for(ll i=sz-1;i>=1;i--){ if(ret[i]>=1&&!ls[ret[i]-1]){ ret[lr[t[ret[i]-1]].se-cnt[t[ret[i]-1]]]=ret[i]-1; cnt[t[ret[i]-1]]++; } } return ret; } ll operator[](const int &k) const{ return data[k]; } }; struct LCP{ SuffixArray sa; vector<int> lcp, rk; LCP(SuffixArray sa):sa(sa), lcp(sa.size), rk(sa.size+1){ rk[sa.size]=0; for(int i=0; i<sa.size; i++){ rk[sa[i]]=i+1; } int h=0; lcp[0]=0; for(int i=0; i<sa.size; i++){ int j=sa[rk[i]-2]; if(h>0) h--; for(; j+h<sa.size && i+h<sa.size; h++){ if(sa.s[j+h]!=sa.s[i+h]) break; } lcp[rk[i]-1]=h; } } int operator[](const int &k) const{ return lcp[k]; } }; template<typename Monoid> struct SegmentTree{ using F=function<Monoid(Monoid, Monoid)>; int sz; vector<Monoid> seg; const F f; const Monoid e; SegmentTree(int n, const F f, const Monoid &e): f(f), e(e){ sz=1; while(sz<n) sz<<=1; seg.resize(2*sz, e); } SegmentTree(int n, const F f, const Monoid &e, vector<Monoid> v): f(f), e(e){ sz=1; while(sz<n) sz<<=1; seg.resize(2*sz, e); for(int i=0; i<n; i++) seg[i+sz]=v[i]; for(int i=sz-1; i>=1; i--){ seg[i]=f(seg[2*i], seg[2*i+1]); } } void update(int k, const Monoid &x){ k+=sz; seg[k]=x; while(k>1){ k>>=1; seg[k]=f(seg[2*k], seg[2*k+1]); } } Monoid query(int a, int b){ a+=sz, b+=sz; Monoid ret=e; for(;a<b; a>>=1, b>>=1){ if(b&1) ret=f(ret, seg[--b]); if(a&1) ret=f(ret, seg[a++]); } return ret; } Monoid operator[](const int &k) const{ return seg[k+sz]; } }; int main() { int n; cin>>n; string s; int id[100010], len[100010]; for(int i=0; i<n; i++){ string si; cin>>si; s+=si; len[i]=si.size(); id[i+1]=id[i]+len[i]; } SuffixArray sa(s); LCP lcp(sa); vector<int> v(s.size()); for(int i=0; i<s.size(); i++) v[i]=lcp[i]; const int INF=1e9+7; SegmentTree<int> seg(s.size(), [](int a, int b){ return min(a, b);}, INF, v); int m; ll x, d; cin>>m>>x>>d; ll ans=0; for(int i=0; i<m; i++){ int p=x/(n-1), q=x%(n-1); if(p>q) swap(p, q); else q++; x=(x+d)%((ll)n*(n-1)); int p1=lcp.rk[id[p]], q1=lcp.rk[id[q]]; if(p1>q1) swap(p1, q1); ans+=min({len[p], len[q], seg.query(p1, q1)}); } cout<<ans<<endl; return 0; }