蓝桥杯 Java k倍区间

蓝桥杯 Java k倍区间_第1张图片

 前缀和的一个神奇算法,这道题暴力是遍历前缀和的差,也就是遍历所有区间和看他是不是能不能正好除尽k

这道题的技巧是将所有前缀和和k求余
按照求余的结果放在一个数组中
那么余数为0的前缀和a一定满足要求([0,a])
余数相同的两两组合范围相减也符合要求,所以有Cn2即 (v[i]*(v[i]-1))/2个

那么就把复杂度为O(n2)的循环遍历前缀和算法降低为复杂度为O(n)的算前缀和余数分类的算法。值得学习。

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int k = scan.nextInt();
        long[] q = new long[n+1];
        long[] v = new long[k];
        for(int i = 1;i <= n;i++){
          q[i] = scan.nextInt() + q[i-1];
          v[(int)(q[i]%k)]++;
        }
        long ans = 0;
        ans += v[0];
        for(int i = 0;i < k;i++){
          ans += (v[i]*(v[i]-1))/2;
        }

        System.out.println(ans);
        //在此输入您的代码...
        scan.close();
    }
}

你可能感兴趣的:(蓝桥杯,1024程序员节,java,算法,蓝桥杯)