結果

問題 No.1018 suffixsuffixsuffix
ユーザー 👑 hos.lyrichos.lyric
提出日時 2020-04-03 22:33:59
言語 D
(dmd 2.107.1)
結果
AC  
実行時間 674 ms / 2,000 ms
コード長 4,824 bytes
コンパイル時間 2,586 ms
コンパイル使用メモリ 164,648 KB
実行使用メモリ 16,856 KB
最終ジャッジ日時 2023-09-04 07:10:54
合計ジャッジ時間 15,783 ms
ジャッジサーバーID
(参考情報)
judge13 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,376 KB
testcase_01 AC 1 ms
4,380 KB
testcase_02 AC 2 ms
4,376 KB
testcase_03 AC 1 ms
4,380 KB
testcase_04 AC 2 ms
4,380 KB
testcase_05 AC 2 ms
4,380 KB
testcase_06 AC 1 ms
4,376 KB
testcase_07 AC 2 ms
4,376 KB
testcase_08 AC 2 ms
4,376 KB
testcase_09 AC 139 ms
12,080 KB
testcase_10 AC 140 ms
12,452 KB
testcase_11 AC 138 ms
11,844 KB
testcase_12 AC 120 ms
11,616 KB
testcase_13 AC 122 ms
11,620 KB
testcase_14 AC 337 ms
13,804 KB
testcase_15 AC 563 ms
15,252 KB
testcase_16 AC 594 ms
15,396 KB
testcase_17 AC 551 ms
14,552 KB
testcase_18 AC 359 ms
13,300 KB
testcase_19 AC 59 ms
6,720 KB
testcase_20 AC 59 ms
6,900 KB
testcase_21 AC 60 ms
6,872 KB
testcase_22 AC 60 ms
7,044 KB
testcase_23 AC 62 ms
7,024 KB
testcase_24 AC 539 ms
15,416 KB
testcase_25 AC 674 ms
16,620 KB
testcase_26 AC 543 ms
16,040 KB
testcase_27 AC 543 ms
15,756 KB
testcase_28 AC 535 ms
15,140 KB
testcase_29 AC 174 ms
10,536 KB
testcase_30 AC 167 ms
10,280 KB
testcase_31 AC 164 ms
9,940 KB
testcase_32 AC 168 ms
10,156 KB
testcase_33 AC 172 ms
9,780 KB
testcase_34 AC 1 ms
4,376 KB
testcase_35 AC 62 ms
7,076 KB
testcase_36 AC 167 ms
11,564 KB
testcase_37 AC 609 ms
16,856 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
Main.d(63): Deprecation: function `std.math.exponential.log10` is deprecated - `std.math.exponential.log10` called with argument types `(int)` matches both `log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.
Main.d(97):        instantiated from here: `SuffixArray!(immutable(char))`

ソースコード

diff #

import std.conv, std.functional, std.range, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.bitmanip, std.complex, std.container, std.math, std.mathspecial, std.numeric, std.regex, std.typecons;
import core.bitop;

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }

bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } }
bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } }

int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; }
int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); }
int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); }

struct SuffixArray(T) {
  import std.algorithm : sort;
  int n;
  T[] ts;
  int[] us, su, lcp;
  this(T)(T[] ts) {
    n = cast(int)(ts.length);
    this.ts = ts;
    us = new int[n + 1];
    su = new int[n + 1];
    foreach (i; 0 .. n + 1) us[i] = i;
    us.sort!((u, v) => (cmp(u, v) < 0));
    auto vals = new int[n + 1], cnt = new int[n + 1], tmp = new int[n + 1];
    foreach (i; 0 .. n) vals[i + 1] = vals[i] + ((cmp(us[i], us[i + 1]) < 0) ? 1 : 0);
    for (int h = 1; ; h <<= 1) {
      int ahead(int i) {
        return (us[i] + h <= n) ? su[us[i] + h] : 0;
      }
      foreach (i; 0 .. n + 1) su[us[i]] = vals[i];
      if (vals[n] == n) break;
      cnt[] = 0;
      foreach (i; 0 .. n + 1) ++cnt[ahead(i)];
      foreach (j; 0 .. n) cnt[j + 1] += cnt[j];
      foreach_reverse (i; 0 .. n + 1) tmp[--cnt[ahead(i)]] = us[i];
      cnt[] = 0;
      foreach (i; 0 .. n + 1) ++cnt[su[tmp[i]]];
      foreach (j; 0 .. n) cnt[j + 1] += cnt[j];
      foreach_reverse (i; 0 .. n + 1) us[--cnt[su[tmp[i]]]] = tmp[i];
      foreach (i; 0 .. n) vals[i + 1] = vals[i] + ((su[us[i]] < su[us[i + 1]] || ahead(i) < ahead(i + 1)) ? 1 : 0);
    }
    lcp = new int[n];
    int h;
    foreach (u; 0 .. n) {
      for (int v = us[su[u] - 1]; cmp(u + h, v + h) == 0; ++h) {}
      lcp[su[u] - 1] = h;
      if (h > 0) --h;
    }
  }
  int cmp(int u, int v) const {
    return (u == n) ? ((v == n) ? 0 : -1) : (v == n) ? +1 : (ts[u] < ts[v]) ? -1 : (ts[u] > ts[v]) ? +1 : 0;
  }
  void print() const {
    import std.math : log10;
    import std.stdio : writefln;
    const numDigits = cast(int)(log10(n)) + 1;
    foreach (i; 0 .. n + 1) {
      writefln("%*d %s", numDigits, us[i], ts[us[i] .. $]);
    }
  }
}



void main() {
  try {
    for (; ; ) {
      const N = readInt();
      const M = readLong();
      const Q = readInt();
      const S = readToken();
      auto K = new long[Q];
      foreach (q; 0 .. Q) {
        K[q] = readLong();
      }
      
      /*
      debug {
        string sh;
        foreach (h; 1 .. 4 + 1) {
          sh ~= S;
          const sah = new SuffixArray!(immutable(char))(sh);
          sah.print;
          writeln("----");
        }
        writeln("====");
      }
      //*/
      
      const sa = new SuffixArray!(immutable(char))(S);
      debug {
        sa.print;
      }
      int n = N;
      {
        int mn = N;
        foreach_reverse (i; 0 .. sa.su[0]) {
          chmin(mn, sa.lcp[i]);
          if (mn == N - sa.us[i] && N % sa.us[i] == 0) {
            chmin(n, sa.us[i]);
          }
        }
      }
      {
        int mn = N;
        foreach (i; sa.su[0] .. N) {
          chmin(mn, sa.lcp[i]);
          if (mn == N - sa.us[i + 1] && N % sa.us[i + 1] == 0) {
            chmin(n, sa.us[i + 1]);
          }
        }
      }
      
      const m = M * (N / n);
      string s;
      foreach (j; 0 .. min(m, 3)) {
        s ~= S[0 .. n];
      }
      const sa0 = new SuffixArray!(immutable(char))(s);
      debug {
        writeln("n = ", n);
        writeln("m = ", m);
        sa0.print;
      }
      
      auto ans = new long[Q];
      if (m <= 3) {
        foreach (q; 0 .. Q) {
          ans[q] = sa0.us[K[q]];
        }
      } else {
        long k = 0;
        int q = 0;
        foreach (i; 0 .. sa0.n + 1) {
          const dk = (sa0.us[i] < n) ? (m - 2) : 1;
          for (; q < Q && k <= K[q] && K[q] < k + dk; ++q) {
            ans[q] = sa0.us[i] + n * (m - 3 - (K[q] - k));
          }
          k += dk;
        }
      }
      foreach (q; 0 .. Q) {
        if (q > 0) write(" ");
        write(ans[q] + 1);
      }
      writeln();
    }
  } catch (EOFException e) {
  }
}
0