小蓝有一个长度为 �n 的数组 �=(�1,�2,⋯,��)A=(a1,a2,⋯,an), 数组的子数组被定义为从 原数组中选出连续的一个或多个元素组成的数组。数组的最大公约数指的是数 组中所有元素的最大公约数。如果最多更改数组中的一个元素之后, 数组的最 大公约数为 �g, 那么称 �g 为这个数组的近似 GCD。一个数组的近似 GCD 可能 有多种取值。
具体的, 判断 �g 是否为一个子数组的近似 GCD 如下:
-
如果这个子数组的最大公约数就是 �g, 那么说明 �g 是其近似 GCD。
-
在修改这个子数组中的一个元素之后 (可以改成想要的任何值), 子数 组的最大公约数为 �g, 那么说明 �g 是这个子数组的近似 GCD。
小蓝想知道, 数组 �A 有多少个长度大于等于 2 的子数组满足近似 GCD 的 值为 �g 。
输入格式
输入的第一行包含两个整数 �,�n,g, 用一个空格分隔, 分别表示数组 �A 的长 度和 �g 的值。
第二行包含 �n 个整数 �1,�2,⋯,��a1,a2,⋯,an, 相邻两个整数之间用一个空格分隔。
输出格式
输出一行包含一个整数表示数组 �A 有多少个长度大于等于 2 的子数组的近 似 ���GCD 的值为 �g 。
样例输入
5 3
1 3 6 4 10
样例输出
5
样例说明
满足条件的子数组有 5 个:
[1,3][1,3] : 将 1 修改为 3 后, 这个子数组的最大公约数为 3 , 满足条件。
[1,3,6][1,3,6] : 将 1 修改为 3 后, 这个子数组的最大公约数为 3 , 满足条件。
[3,6]:这个子数组的最大公约数就是 3 , 满足条件。
[3,6,4][3,6,4] : 将 4 修改为 3 后, 这个子数组的最大公约数为 3 , 满足条件。
[6,4][6,4] : 将 4 修改为 3 后, 这个子数组的最大公约数为 3 , 满足条件。
评测用例规模与约定
对于 20%20% 的评测用例, 2≤�≤1022≤n≤102 ;
对于 40%40% 的评测用例, 2≤�≤1032≤n≤103;
对于所有评测用例, 2≤�≤105,1≤�,��≤1092≤n≤105,1≤g,ai≤109 。
运行限制
- 最大运行时间:1s
- 最大运行内存: 512M
思路:先求出需要修改的的次数,使用前缀和Sum数组,枚举左端点,二分右端点,找出一个小于等于1的区间。
import java.io.*;
import java.math.BigInteger;
import java.util.StringTokenizer;
public class Main {
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException {
int n = sc.nextInt();
int t = sc.nextInt();
int[] a = new int[n + 1];
int[] sum = new int[n + 1];
for (int i = 1; i <= n; i++) {
a[i] = sc.nextInt();
if (a[i] % t != 0) sum[i]++;
}
for (int i = 1; i <= n; i++) {
sum[i] += sum[i - 1];
}
long cnt = 0;
for (int i = 1; i <= n; i++) {
int l = i, r = n;
while (l < r) {
int mid = l + r + 1 >> 1;
if (sum[mid] - sum[i - 1] <= 1) {
l = mid;
} else {
r = mid - 1;
}
}
cnt += l - i;
}
out.println(cnt);
}
static class sc {
private static final StreamTokenizer input = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static int nextInt() throws IOException {
input.nextToken();
return (int) input.nval;
}
}
}