你能求出数列中总共有多少个K倍区间吗?
输入
第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)
输出
输出一个整数,代表K倍区间的数目。
例如,
输入:
5 2
1
2
3
4
5
程序应该输出:
6
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
===========
思路:
双层嵌套for,控制移动指针bgn,end->任意读取一段输入
{全集=(i)+(i +1) +…(i +k)}
,这里的全集由双层for的结构得出,判断是否为k倍区间->复杂=O(n^2)->输入规模较大时->超时×
为使复杂度为O(n)->减少一层for的枚举->减少一个移动指针,将起点指针固定在头部,移动终点指针,多声明一个数组空间保存每一次输入后的前缀和的对于k的模(两端数据的起点相同,对K值取得的模也相同,说明两者差值恰为k区间)->此时
{全集=为K区间的第i项前缀和的个数+为K区间的第i项前缀和与之前前缀和的差值}
来一波ppt作图
public class k倍区间 {
static int[] sum =new int[100001]; //前i项和
static int[] cnt =new int[100001]; //前缀和的模的出现次数(count简写)
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n =sc.nextInt();
int k =sc.nextInt();
long ans =0L;
int tmp_numb =0;
for(int i =1 ;i <=n ;i ++) {
tmp_numb =sc.nextInt(); //第i项输入
sum[i] =(sum[i -1] +tmp_numb) %k; //第i项前缀和的模
ans +=cnt[sum[i]]; //第i项之前模的出现次数->存在几段差值恰为k倍的区间
cnt[sum[i]] ++; //累加前缀和的模的出现次数
}
sc.close();
System.out.println(ans +cnt[0]); //输出全集=前缀和为K区间的个数+前缀和差值为k区间的个数
}
}