結果
| 問題 | 
                            No.515 典型LCP
                             | 
                    
| コンテスト | |
| ユーザー | 
                             r_dream0
                         | 
                    
| 提出日時 | 2017-05-08 12:18:15 | 
| 言語 | C++14  (gcc 13.3.0 + boost 1.87.0)  | 
                    
| 結果 | 
                             
                                TLE
                                 
                             
                            
                         | 
                    
| 実行時間 | - | 
| コード長 | 2,169 bytes | 
| コンパイル時間 | 1,420 ms | 
| コンパイル使用メモリ | 86,408 KB | 
| 実行使用メモリ | 8,960 KB | 
| 最終ジャッジ日時 | 2024-09-14 17:17:06 | 
| 合計ジャッジ時間 | 13,291 ms | 
| 
                            ジャッジサーバーID (参考情報)  | 
                        judge1 / judge6 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 2 | 
| other | AC * 13 TLE * 2 | 
ソースコード
#include <vector>
#include <climits>
#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
#define REP(i,x) for(int i = 0; i < (int)(x); i++)
// LCPを計算する O(N)
vector<int> build_lcp(const string &s, vector<int> sa){
  int n = s.size(), h = 0;
  vector<int> rank(n + 1), lcp(n + 1);
  REP(i, n + 1) rank[sa[i]] = i;
  REP(i, n){
    int j = sa[rank[i] - 1];
    if(h > 0) h--;
    for(; j + h < n && i + h < n; h++){
      if(s[j + h] != s[i + h])break;
    }
    lcp[rank[i] -1] = h;
  }
  return lcp;
}
class RMQ{
  private:
    vector<int> val;
    int n;
  public:
    RMQ(int size){
      n=1;
      while(n<size)n<<=1;
      val=vector<int>(2*n,INT_MAX);
    }
    //x番目の要素をaに更新する
    void update(int x,int a){
      x+=n-1;
      val[x]=a;
      while(x>0){
        x=(x-1)/2;
        val[x]=min(val[x*2+1],val[x*2+2]);
      }
    }
    //a<=x<b
    int minimum(int a,int b,int k=0,int l=0,int r=-1){
      if(r==-1)r=n;
      if(r<=a||b<=l)return INT_MAX;
      if(a<=l&&r<=b){
        return val[k];
      }else{
        return min(minimum(a,b,k*2+1,l,(l+r)/2),minimum(a,b,k*2+2,(l+r)/2,r));
      }
    }
};
int main() {
  int N;
  cin >> N;
  vector<int> inv(N);
  vector<pair<string, int> > s(N);
  for(int i = 0; i < N; i++) {
    cin >> s[i].first;
    s[i].second = i;
  }
  sort(s.begin(), s.end());
  for(int i = 0; i < N; i++) {
    inv[s[i].second] = i;
  }
  vector<int> lcp(N - 1);
  for(int i = 0; i < N - 1; i++) {
    for(int j = 0; j < min(s[i].first.size(), s[i + 1].first.size()); j++) {
      if(s[i].first[j] == s[i + 1].first[j]) lcp[i] = j + 1; else break;
    }
  }
  RMQ rmq(N - 1);
  for(int i = 0; i < N - 1; i++) {
    rmq.update(i, lcp[i]);
  }
  int M;
  cin >> M;
  int64_t x, d;
  cin >> x >> d;
  int64_t answer = 0;
  for(int i = 0; i < M; i++) {
    int64_t ii = x / (N - 1);
    int64_t jj = x % (N - 1);
    if(ii > jj) {
      swap(ii, jj);
    } else {
      jj++;
    }
    int ipos = inv[ii];
    int jpos = inv[jj];
    if(ipos > jpos) swap(ipos, jpos);
    answer += rmq.minimum(ipos, jpos);
    x = (x + d) % (N * (N - 1));
  }
  cout << answer << endl;
}
            
            
            
        
            
r_dream0