結果
| 問題 |
No.515 典型LCP
|
| コンテスト | |
| ユーザー |
chocorusk
|
| 提出日時 | 2019-10-27 14:48:45 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 817 ms / 1,000 ms |
| コード長 | 5,286 bytes |
| コンパイル時間 | 1,746 ms |
| コンパイル使用メモリ | 137,772 KB |
| 実行使用メモリ | 99,608 KB |
| 最終ジャッジ日時 | 2024-09-14 21:03:01 |
| 合計ジャッジ時間 | 8,685 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 15 |
ソースコード
#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];
}
};
vector<vector<int>> spt;
vector<int> vlog;
void sparsetable_build(const vector<int> &v){
int b=0, n=v.size();
while((1<<b)<=n) b++;
spt.resize(b, vector<int>(n));
for(int i=0; i<n; i++) spt[0][i]=v[i];
for(int i=1; i<b; i++){
for(int j=0; j+(1<<i)<=n; j++){
spt[i][j]=min(spt[i-1][j], spt[i-1][j+(1<<(i-1))]);
}
}
vlog.resize(n+1);
for(int i=2; i<=n; i++) vlog[i]=vlog[i>>1]+1;
}
inline int rmq(int l, int r){
int b=vlog[r-l];
return min(spt[b][l], spt[b][r-(1<<b)]);
}
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];
sparsetable_build(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], rmq(p1, q1)});
}
cout<<ans<<endl;
return 0;
}
chocorusk