Skip to content

Commit 0123f59

Browse files
author
uwi
committed
'saNaiveとsaDoublingを高速化。しきい値調整。'
1 parent 03f55f4 commit 0123f59

2 files changed

Lines changed: 74 additions & 7 deletions

File tree

‎StringAlgorithm/StringAlgorithm.java‎

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ private static int[] saNaive(int[] s) {
1818
return sa;
1919
}
2020

21-
public static int[] saDoubling(int[] s) {
21+
private static int[] saDoubling(int[] s) {
2222
int n = s.length;
2323
int[] sa = new int[n];
2424
for(int i = 0;i < n;i++){
@@ -36,7 +36,7 @@ public static int[] saDoubling(int[] s) {
3636
int ry = y + _k < n ? _rnk[y + _k] : -1;
3737
return rx - ry;
3838
};
39-
insertionsortUsingComparator(sa, cmp);
39+
mergesortUsingComparator(sa, cmp);
4040
tmp[sa[0]] = 0;
4141
for (int i = 1; i < n; i++) {
4242
tmp[sa[i]] = tmp[sa[i - 1]] + (cmp.applyAsInt(sa[i - 1], sa[i]) < 0 ? 1 : 0);
@@ -63,8 +63,33 @@ private static void insertionsortUsingComparator(int[] a, java.util.function.Int
6363
}
6464
}
6565

66-
private static final int THRESHOLD_NAIVE = 10;
67-
private static final int THRESHOLD_DOUBLING = 40;
66+
private static void mergesortUsingComparator(int[] a, java.util.function.IntBinaryOperator comparator) {
67+
final int n = a.length;
68+
final int[] work = new int[n];
69+
for (int block = 1; block <= n; block <<= 1) {
70+
final int block2 = block << 1;
71+
for (int l = 0, max = n - block; l < max; l += block2) {
72+
int m = l + block;
73+
int r = Math.min(l + block2, n);
74+
System.arraycopy(a, l, work, 0, block);
75+
for (int i = l, wi = 0, ti = m;; i++) {
76+
if (ti == r) {
77+
System.arraycopy(work, wi, a, i, block - wi);
78+
break;
79+
}
80+
if (comparator.applyAsInt(work[wi], a[ti]) > 0) {
81+
a[i] = a[ti++];
82+
} else {
83+
a[i] = work[wi++];
84+
if (wi == block) break;
85+
}
86+
}
87+
}
88+
}
89+
}
90+
91+
private static final int THRESHOLD_NAIVE = 50;
92+
private static final int THRESHOLD_DOUBLING = 0;
6893

6994
private static int[] sais(int[] s, int upper) {
7095
int n = s.length;
@@ -80,9 +105,9 @@ private static int[] sais(int[] s, int upper) {
80105
if (n < THRESHOLD_NAIVE) {
81106
return saNaive(s);
82107
}
83-
if (n < THRESHOLD_DOUBLING) {
84-
return saDoubling(s);
85-
}
108+
// if (n < THRESHOLD_DOUBLING) {
109+
// return saDoubling(s);
110+
// }
86111

87112
int[] sa = new int[n];
88113
boolean[] ls = new boolean[n];
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# クラス FenwickTree
2+
3+
長さ $N$ の long型配列に対し,
4+
5+
* 要素の1点変更
6+
* 区間の要素の総和
7+
8+
を $O(\log N)$ の時間で求めることができるデータ構造です.
9+
10+
11+
## コンストラクタ
12+
### FenwickTree
13+
```java
14+
public FenwickTree(int n)
15+
```
16+
17+
長さ $n$ の配列 $a_0, a_1, \dots, a_{n-1}$を作ります. 初期値はすべて0です.
18+
計算量: $O(n)$
19+
20+
```java
21+
public FenwickTree(long[] data)
22+
```
23+
24+
長さ $n$ の配列 $a_0, a_1, \dots, a_{n-1}$を `data` により初期化します.
25+
計算量: $O(n)$
26+
27+
## メソッド
28+
### add
29+
```java
30+
public void add(int p, long x)
31+
```
32+
配列の第$p$要素に$x$を加える. すなわち, `a[p] += x` のこと.
33+
計算量: $O(\log N)$
34+
35+
### sum
36+
```java
37+
public long sum(int l, int r)
38+
```
39+
$a_l + a_{l+1} + \dots + a_{r-1}$の値を返す. 計算量: $O(\log n)$
40+
41+
## 使用例
42+
[[https://atcoder.jp/contests/practice2/submissions/16573339]]

0 commit comments

Comments
 (0)