Zero Remainder Array

it2025-06-26  5

原题链接:https://vjudge.net/problem/CodeForces-1374D/origin

You are given an array a consisting of n positive integers.

Initially, you have an integer x=0. During one move, you can do one of the following two operations:

Choose exactly one i from 1 to n and increase ai by x (ai:=ai+x), then increase x by 1 (x:=x+1). Just increase x by 1 (x:=x+1). The first operation can be applied no more than once to each i from 1 to n.

Your task is to find the minimum number of moves required to obtain such an array that each its element is divisible by k (the value k is given).

You have to answer t independent test cases.

Input The first line of the input contains one integer t (1≤t≤2⋅104) — the number of test cases. Then t test cases follow.

The first line of the test case contains two integers n and k (1≤n≤2⋅105;1≤k≤109) — the length of a and the required divisior. The second line of the test case contains n integers a1,a2,…,an (1≤ai≤109), where ai is the i-th element of a.

It is guaranteed that the sum of n does not exceed 2⋅105 (∑n≤2⋅105).

Output For each test case, print the answer — the minimum number of moves required to obtain such an array that each its element is divisible by k.

题目大意:一个长度为n的数组,将里面的数全部操作为k的倍数。问最少需要操作多少步。X从0开始,数组元素可执行:ai += x,每次执行后,x都要++.

思路:因为最后都是k的倍数,所以如果 ai = k-1 和 aj = 2*k-1,需要执行的操作都是 (+1);(但是因为 x 的每个值只能被加一次,,所以 ai 执行(ai+1)后 aj 就要执行(aj+k+1)才能是k的倍数,,这样我们把数组的数都变成k - ( a[i] % k),然后用map保存,,如果有重复就 x = 重复个数 * k + a[i],这样最后的最大x,就是最少操作步数。

#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5 +10; ll a[N],b[N],mmax;//k值比较大,所以数据用longlong int main(){ int t; scanf("%d",&t);//用cin也能过 while(t -- > 0){ map<ll,ll>m;//map中数据也要用longlong mmax = -1;//这里需要注意。mmax不能定义为0; ll n,k; scanf("%lld %lld",&n,&k); for(int i = 0; i < n; i ++){ scanf("%lld",&a[i]); a[i] =k-(a[i] %k); if(a[i] != k){//如果等于k就说明这个ai已经是k的倍数了,不需要执行操作了。 if(m.count(a[i])){ mmax = max(mmax,a[i]+m[a[i]]*k); m[a[i]]+= 1; } else{ m[a[i]] = 1; mmax = max(mmax,a[i]); } } } cout<<mmax+1<<'\n';//输出+1是因为x=0也算一步。 } }
最新回复(0)