Skip to content

Commit 30a54dc

Browse files
committed
Improved task 3448
1 parent f630202 commit 30a54dc

File tree

1 file changed

+79
-39
lines changed
  • src/main/java/g3401_3500/s3448_count_substrings_divisible_by_last_digit

1 file changed

+79
-39
lines changed

src/main/java/g3401_3500/s3448_count_substrings_divisible_by_last_digit/Solution.java

Lines changed: 79 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,63 +5,103 @@
55
public class Solution {
66
public long countSubstrings(String s) {
77
int n = s.length();
8-
long ans = 0;
98
int[] p3 = new int[n];
109
int[] p7 = new int[n];
1110
int[] p9 = new int[n];
11+
computeModArrays(s, p3, p7, p9);
12+
long[] freq3 = new long[3];
13+
long[] freq9 = new long[9];
14+
long[][] freq7 = new long[6][7];
15+
int[] inv7 = {1, 5, 4, 6, 2, 3};
16+
return countValidSubstrings(s, p3, p7, p9, freq3, freq9, freq7, inv7);
17+
}
18+
19+
private void computeModArrays(String s, int[] p3, int[] p7, int[] p9) {
1220
p3[0] = (s.charAt(0) - '0') % 3;
1321
p7[0] = (s.charAt(0) - '0') % 7;
1422
p9[0] = (s.charAt(0) - '0') % 9;
15-
for (int i = 1; i < n; i++) {
23+
for (int i = 1; i < s.length(); i++) {
1624
int dig = s.charAt(i) - '0';
1725
p3[i] = (p3[i - 1] * 10 + dig) % 3;
1826
p7[i] = (p7[i - 1] * 10 + dig) % 7;
1927
p9[i] = (p9[i - 1] * 10 + dig) % 9;
2028
}
21-
long[] freq3 = new long[3];
22-
long[] freq9 = new long[9];
23-
long[][] freq7 = new long[6][7];
24-
int[] inv7 = {1, 5, 4, 6, 2, 3};
25-
for (int j = 0; j < n; j++) {
29+
}
30+
31+
private long countValidSubstrings(
32+
String s,
33+
int[] p3,
34+
int[] p7,
35+
int[] p9,
36+
long[] freq3,
37+
long[] freq9,
38+
long[][] freq7,
39+
int[] inv7) {
40+
long ans = 0;
41+
for (int j = 0; j < s.length(); j++) {
2642
int d = s.charAt(j) - '0';
2743
if (d != 0) {
28-
if (d == 1 || d == 2 || d == 5) {
29-
ans += (j + 1);
30-
} else if (d == 4) {
31-
if (j == 0) {
32-
ans += 1;
33-
} else {
34-
int num = (s.charAt(j - 1) - '0') * 10 + d;
35-
ans += (num % 4 == 0 ? (j + 1) : 1);
36-
}
37-
} else if (d == 8) {
38-
if (j == 0) {
39-
ans += 1;
40-
} else if (j == 1) {
41-
int num = (s.charAt(0) - '0') * 10 + 8;
42-
ans += (num % 8 == 0 ? 2 : 1);
43-
} else {
44-
int num3 = (s.charAt(j - 2) - '0') * 100 + (s.charAt(j - 1) - '0') * 10 + 8;
45-
int num2 = (s.charAt(j - 1) - '0') * 10 + 8;
46-
ans += ((num3 % 8 == 0 ? (j - 1) : 0) + (num2 % 8 == 0 ? 1 : 0) + 1);
47-
}
48-
} else if (d == 3 || d == 6) {
49-
ans += (p3[j] == 0 ? 1L : 0L) + freq3[p3[j]];
50-
} else if (d == 7) {
51-
ans += (p7[j] == 0 ? 1L : 0L);
52-
for (int m = 0; m < 6; m++) {
53-
int idx = ((j % 6) - m + 6) % 6;
54-
int req = (p7[j] * inv7[m]) % 7;
55-
ans += freq7[idx][req];
56-
}
57-
} else if (d == 9) {
58-
ans += (p9[j] == 0 ? 1L : 0L) + freq9[p9[j]];
59-
}
44+
ans += countDivisibilityCases(s, j, d, p3, p7, p9, freq3, freq9, freq7, inv7);
6045
}
6146
freq3[p3[j]]++;
6247
freq7[j % 6][p7[j]]++;
6348
freq9[p9[j]]++;
6449
}
6550
return ans;
6651
}
52+
53+
private long countDivisibilityCases(
54+
String s,
55+
int j,
56+
int d,
57+
int[] p3,
58+
int[] p7,
59+
int[] p9,
60+
long[] freq3,
61+
long[] freq9,
62+
long[][] freq7,
63+
int[] inv7) {
64+
long ans = 0;
65+
if (d == 1 || d == 2 || d == 5) {
66+
ans += (j + 1);
67+
} else if (d == 4) {
68+
ans += countDivisibilityBy4(s, j);
69+
} else if (d == 8) {
70+
ans += countDivisibilityBy8(s, j);
71+
} else if (d == 3 || d == 6) {
72+
ans += (p3[j] == 0 ? 1L : 0L) + freq3[p3[j]];
73+
} else if (d == 7) {
74+
ans += countDivisibilityBy7(j, p7, freq7, inv7);
75+
} else if (d == 9) {
76+
ans += (p9[j] == 0 ? 1L : 0L) + freq9[p9[j]];
77+
}
78+
return ans;
79+
}
80+
81+
private long countDivisibilityBy4(String s, int j) {
82+
if (j == 0) return 1;
83+
int num = (s.charAt(j - 1) - '0') * 10 + (s.charAt(j) - '0');
84+
return num % 4 == 0 ? j + 1 : 1;
85+
}
86+
87+
private long countDivisibilityBy8(String s, int j) {
88+
if (j == 0) return 1;
89+
if (j == 1) {
90+
int num = (s.charAt(0) - '0') * 10 + 8;
91+
return (num % 8 == 0 ? 2 : 1);
92+
}
93+
int num3 = (s.charAt(j - 2) - '0') * 100 + (s.charAt(j - 1) - '0') * 10 + 8;
94+
int num2 = (s.charAt(j - 1) - '0') * 10 + 8;
95+
return (num3 % 8 == 0 ? j - 1 : 0) + (num2 % 8 == 0 ? 1 : 0) + 1;
96+
}
97+
98+
private long countDivisibilityBy7(int j, int[] p7, long[][] freq7, int[] inv7) {
99+
long ans = (p7[j] == 0 ? 1L : 0L);
100+
for (int m = 0; m < 6; m++) {
101+
int idx = ((j % 6) - m + 6) % 6;
102+
int req = (p7[j] * inv7[m]) % 7;
103+
ans += freq7[idx][req];
104+
}
105+
return ans;
106+
}
67107
}

0 commit comments

Comments
 (0)