CF Codeforces Round #490 (Div. 3) D. Equalize the Remainders

You are given an array consisting of nn integers a1,a2,…,ana1,a2,…,an, and a positive integer mm. It is guaranteed that mm is a divisor of nn.

In a single move, you can choose any position ii between 11 and nn and increase aiai by 11.

Let's calculate crcr (0≤r≤m−1)0≤r≤m−1) — the number of elements having remainder rr when divided by mm. In other words, for each remainder, let's find the number of corresponding elements in aa with that remainder.

Your task is to change the array in such a way that c0=c1=⋯=cm−1=nmc0=c1=⋯=cm−1=nm.

Find the minimum number of moves to satisfy the above requirement.

Input

The first line of input contains two integers nn and mm (1≤n≤2⋅105,1≤m≤n1≤n≤2⋅105,1≤m≤n). It is guaranteed that mm is a divisor of nn.

The second line of input contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai≤1090≤ai≤109), the elements of the array.

Output

In the first line, print a single integer — the minimum number of moves required to satisfy the following condition: for each remainder from 00 to m−1m−1, the number of elements of the array having this remainder equals nmnm.

In the second line, print any array satisfying the condition and can be obtained from the given array with the minimum number of moves. The values of the elements of the resulting array must not exceed 10181018.

Examples

input

Copy

6 3
3 2 0 6 10 12

output

Copy

3
3 2 0 7 10 14 

input

Copy

4 2
0 1 2 3

output

Copy

0
0 1 2 3 

题意:

     就是n个数,对m取余,要求每个余数都为n/m个,不满可以是这个数+1,求出加了多少1,并且输出数列

思路:

      由于每次直接加,所以大的余数只能从小的数得来,如果不能从小的得来,那就只能从大的哪里加模得到。

#include <iostream>
#include <vector>
struct ac{
    int elem, i;
    ac () {}
    ac (int &_elem, int &_i) {
        elem = _elem, i = _i;
    }
};
using namespace std;
int main() {
    int n, m;
    cin >> n >> m;
    int k = n / m;
    vector<int> a(n);
    vector<int> val[m];
    for (int i = 0; i < n; i ++) {
        cin >> a[i];
        val[a[i] % m].push_back(i);//储存余数相同的数的下标
    }
    long long ans = 0;
    vector<ac> fre;
    for (int i = 0; i < 2 * m; i ++) {//一旦出现对于i[0,m - 1]前面的数字不能补全i,那么他就只能从后面找,而且只能找距离他最远的有多余值的数,所以i的范围是[0, 2m)
        int cur = i % m;//当前的余数
        while(int(val[cur].size()) > k) {//如果这个余数的数量大于k,就减到k个
            int elem = val[cur].back();
            val[cur].pop_back();
            fre.push_back(ac(elem, i));//添加到fre中
        }
        while(int(val[cur].size()) < k && !fre.empty()) {//如果小于的话,那就只能从前面找能不能补全
            int elem = fre.back().elem;
            int mmod = fre.back().i;
            fre.pop_back();//能补,把前面的pop掉
            val[cur].push_back(elem);//加到val【vur】中
            a[elem] += i - mmod;//把数字的余数加到cur
            ans += i - mmod;//ans数加上操作数
        }
    }
    cout << ans << endl;
    for (int i = 0; i < n; i ++)
        cout << a[i] << " ";
    cout << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/81123119