結果

問題 No.430 文字列検索
ユーザー HaarHaar
提出日時 2019-05-17 07:46:20
言語 C++14
(gcc 13.2.0 + boost 1.83.0)
結果
AC  
実行時間 441 ms / 2,000 ms
コード長 3,099 bytes
コンパイル時間 1,858 ms
コンパイル使用メモリ 180,960 KB
実行使用メモリ 6,944 KB
最終ジャッジ日時 2023-10-17 07:10:12
合計ジャッジ時間 5,871 ms
ジャッジサーバーID
(参考情報)
judge11 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,348 KB
testcase_01 AC 440 ms
6,944 KB
testcase_02 AC 52 ms
6,944 KB
testcase_03 AC 53 ms
6,944 KB
testcase_04 AC 2 ms
4,348 KB
testcase_05 AC 2 ms
4,348 KB
testcase_06 AC 2 ms
4,348 KB
testcase_07 AC 2 ms
4,348 KB
testcase_08 AC 441 ms
6,900 KB
testcase_09 AC 2 ms
4,348 KB
testcase_10 AC 20 ms
4,348 KB
testcase_11 AC 400 ms
6,944 KB
testcase_12 AC 403 ms
6,944 KB
testcase_13 AC 419 ms
6,944 KB
testcase_14 AC 393 ms
6,944 KB
testcase_15 AC 387 ms
6,944 KB
testcase_16 AC 281 ms
6,944 KB
testcase_17 AC 160 ms
6,944 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
#define FOR(v, a, b) for(int v = (a); v < (b); ++v)
#define FORE(v, a, b) for(int v = (a); v <= (b); ++v)
#define REP(v, n) FOR(v, 0, n)
#define REPE(v, n) FORE(v, 0, n)
#define REV(v, a, b) for(int v = (a); v >= (b); --v)
#define ALL(x) (x).begin(), (x).end()
#define RALL(x) (x).rbegin(), (x).rend()
#define ITR(it, c) for(auto it = (c).begin(); it != (c).end(); ++it)
#define RITR(it, c) for(auto it = (c).rbegin(); it != (c).rend(); ++it)
#define EXIST(c,x) ((c).find(x) != (c).end())
#define LLI long long int
#define fst first
#define snd second
#define popcount __builtin_popcount

#ifdef DEBUG
#include <misc/C++/Debug.cpp>
#else
#define dump(x) ((void)0)
#endif

#define gcd __gcd

using namespace std;
template <class T> constexpr T lcm(T m, T n){return m/gcd(m,n)*n;}

template <typename I> void join(ostream &ost, I s, I t, string d=" "){for(auto i=s; i!=t; ++i){if(i!=s)ost<<d; ost<<*i;}ost<<endl;}
template <typename T> istream& operator>>(istream &is, vector<T> &v){for(auto &a : v) is >> a; return is;}
template <typename T, typename U> istream& operator>>(istream &is, pair<T,U> &p){is >> p.first >> p.second; return is;}

template <typename T, typename U> bool chmin(T &a, const U &b){return (a>b ? a=b, true : false);}
template <typename T, typename U> bool chmax(T &a, const U &b){return (a<b ? a=b, true : false);}
template <typename T, size_t N, typename U> void fill_array(T (&a)[N], const U &v){fill((U*)a, (U*)(a+N), v);}

template <typename T> class SuffixArray{
public:
  vector<int> sa;
  const T str;
  
  SuffixArray(const T &s): sa(s.size()), str(s){
    int n = s.size();
    vector<int> temp(n);
    REP(i,n) temp[i] = s[i];

    for(int l=1; l<n; l*=2){
      map<pair<int,int>, int> m2;
      REP(i,n) m2[make_pair(temp[i], i+l>=n?-1:temp[i+l])] = 0;
      int i=0;
      ITR(it,m2) it->second = i++;
      REP(i,n) temp[i] = m2[make_pair(temp[i], i+l>=n?-1:temp[i+l])];
    }
    REP(i,n) sa[temp[i]] = i;
  }

  int operator[](int i){return sa[i];}

  bool starts_with(const T &s, int k){
    if(s.size() <= str.size()-k){
      REP(i,(int)s.size()){
	if(s[i] != str[k+i]) return false;
      }
      return true;
    }
    return false;
  }

  int lower_bound(const T &s){
    auto check =
      [&](int x){
	REP(i,(int)s.size()){
	  if(sa[x]+i >= (int)str.size()) return false;
	  if(s[i] < str[sa[x]+i]) return true;
	  if(s[i] > str[sa[x]+i]) return false;
	}
	return true;
      };

    int lb=-1, ub=sa.size(), mid;
    while(abs(lb-ub)>1){
      mid = (lb+ub)/2;

      if(check(mid)){
	ub = mid;
      }else{
	lb = mid;
      }
    }
    
    return ub;
  }

  int upper_bound(const T &s){
    T t(s);

    t.back()++;
    int ret = lower_bound(t);
    t.back()--;
    return ret;
  }
};


int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);

  string S;
  int M;
  while(cin >> S >> M){
    vector<string> C(M); cin >> C;

    SuffixArray<string> sa(S);
    
    int ans = 0;

    REP(i,M){
      int t = sa.upper_bound(C[i]) - sa.lower_bound(C[i]);
      ans += t;
    }
    
    cout << ans << endl;
  }
  
  return 0;
}
0