Java implementation of k times interval of Blue Bridge Cup

Title: The title OJ
Insert picture description here
this question would like to think is very good, Interval Problems Well, a look that is incorrect prefix and a written T
because it is clear we direct data 1e5 double loop to determine the absolute T,
so we can put this issue into two To solve this kind of problem, the first is of course to use a [i] to represent the sum of the first i numbers
(1) If a [i]% k == 0, this is needless to say ans ++
(2) Remove the first case, leaving The next step is to subtract, that is, to calculate the difference between the two intervals. Here we can see that what we need to find is (a [i]-a [j])% k == 0, we can see it as a [i]% k == a [j]% k means that as long as the values ​​of these two numbers% k are equal, they can definitely form a K-fold interval. Here we can set an array as cnt []
cnt [i]: The number of% k remainder intervals so that every time we scan a prefix sum, we only need to add it% k and then
ans + = cnt [a [i]], this complexity is greatly reduced. Example OJ
example: the
array is 1 2 3 4 5 k: 2
prefix and 1 3 6 10 15
1: a [i]% k == 1 ans + = cnt [1] = 0 cnt [1] ++
3: a [i]% k == 1 ans + = cnt [1 ] = 1 cnt [1] ++
6: First judge the first case ans ++ (ans = 2) a [i]% k == 0 ans + = cnt [0] = 2 cnt [0] ++
10: First judge the first case ans ++ (ans = 3) a [i]% k == 0 ans + = cnt [0] = 4 cnt [0] ++
15: a [i]% k == 1 ans + = cnt [1] = 6 cnt [0] ++

code

import java.io.*;
public class P7165k倍区间 {
	/*
	 * 用a[i]表示前i个数的和
	 * 一个区间是k的倍数
	 * 二种情况
	 * (1)a[i]是k的倍数 1~i 和为k的倍数 这个时候 ans++
	 * (2)a[i]-a[j]是k的倍数 i~j 和为k的倍数 这个时候我们看成 a[i]%k == a[j]%k
	 *  所以我们只需要每次将每一个前缀和都%k 加入到余数的数组 cnt[t]:表示当前余数为t的区间段有cnt[t]个 ans+=cnt[t]就好了
	 */
	static int N = 100010;
	static int a[] = new int[N];
	static int cnt[] = new int[N];
	static int n;
	static int k;
	static long ans = 0;
	public static void main(String[] args) throws IOException{
		StreamTokenizer re = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter pr = new PrintWriter(new OutputStreamWriter(System.out));
		re.nextToken(); n = (int)re.nval;
		re.nextToken(); k = (int)re.nval;
		for(int i = 1;i <= n;i++){
			re.nextToken();
			a[i] = (int)re.nval;
			a[i] = (a[i]+a[i-1])%k;
			if(a[i] == 0)
				ans++;
			ans += cnt[a[i]];
			cnt[a[i]]++;
		}
		pr.println(ans);
		pr.flush();
	}
}
Published 32 original articles · praised 5 · visits 862

Guess you like

Origin blog.csdn.net/shizhuba/article/details/105301239