MCPcopy Create free account
hub / github.com/algorithmzuo/algorithm-journey / Code03_SquareRoot

Class Code03_SquareRoot

src/class111/Code03_SquareRoot.java:21–124  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

19import java.io.StreamTokenizer;
20
21public class Code03_SquareRoot {
22
23 public static int MAXN = 100001;
24
25 public static long[] arr = new long[MAXN];
26
27 public static long[] sum = new long[MAXN << 2];
28
29 public static long[] max = new long[MAXN << 2];
30
31 public static void up(int i) {
32 sum[i] = sum[i << 1] + sum[i << 1 | 1];
33 max[i] = Math.max(max[i << 1], max[i << 1 | 1]);
34 }
35
36 public static void build(int l, int r, int i) {
37 if (l == r) {
38 sum[i] = arr[l];
39 max[i] = arr[l];
40 } else {
41 int mid = (l + r) >> 1;
42 build(l, mid, i << 1);
43 build(mid + 1, r, i << 1 | 1);
44 up(i);
45 }
46 }
47
48 // sqrt方法是最核心的
49 // 注意和常规线段树不一样,这里没有懒更新,也就不需要有down方法
50 // 只有根据范围最大值信息的剪枝
51 // 时间复杂度的分析就是课上讲的势能分析
52 // 不用纠结单次调用的复杂度
53 // 哪怕调用再多次sqrt方法,总的时间复杂度也就是O(n * 6 * logn)
54 public static void sqrt(int jobl, int jobr, int l, int r, int i) {
55 if (l == r) {
56 long sqrt = (long) Math.sqrt(max[i]);
57 sum[i] = sqrt;
58 max[i] = sqrt;
59 } else {
60 int mid = (l + r) >> 1;
61 if (jobl <= mid && max[i << 1] > 1) {
62 sqrt(jobl, jobr, l, mid, i << 1);
63 }
64 if (jobr > mid && max[i << 1 | 1] > 1) {
65 sqrt(jobl, jobr, mid + 1, r, i << 1 | 1);
66 }
67 up(i);
68 }
69 }
70
71 // 没有懒更新
72 // 不需要调用down方法
73 public static long query(int jobl, int jobr, int l, int r, int i) {
74 if (jobl <= l && r <= jobr) {
75 return sum[i];
76 }
77 int mid = (l + r) >> 1;
78 long ans = 0;

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected