結果
| 問題 |
No.1018 suffixsuffixsuffix
|
| ユーザー |
|
| 提出日時 | 2020-04-03 22:33:59 |
| 言語 | D (dmd 2.109.1) |
| 結果 |
AC
|
| 実行時間 | 646 ms / 2,000 ms |
| コード長 | 4,824 bytes |
| コンパイル時間 | 2,741 ms |
| コンパイル使用メモリ | 168,428 KB |
| 実行使用メモリ | 17,928 KB |
| 最終ジャッジ日時 | 2024-06-22 06:30:12 |
| 合計ジャッジ時間 | 14,633 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 34 |
コンパイルメッセージ
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))`
ソースコード
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) {
}
}