# CoderForces999D-Equalize the Remainders（set函数的应用）

## SET

set，集合，会默认从小到大排序并去重（unordered_set 是不排序的集合，节省时间，提高效率）

set<int> s;

1. s.insert(i)    向集合中插入元素i

2. s.begin()     s的初始位置

3. s.end()        s的末位置

4. s.erase(i)     删除元素i，如果找不到则不删除

5. a.find(i)        查找元素i，若找到，则返回地址

6.a.lower_bound(i)        查找大于等于i的第一个元素，返回地址

## Equalize the Remainders

You are given an array consisting of n integersa1,a2,…,an, and a positive integer m. It is guaranteed that m is a divisor of n.

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

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

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

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

The first line of input contains two integers n and m (1≤n≤2⋅10^5,1≤m≤n). It is guaranteed that m is a divisor of n.

The second line of input contains n integers a1,a2,…,an (0≤ai≤10^9), the elements of the array.

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

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 10^18.

#include <iostream>
#include <set>
#include <cstdio>
#include <cstring>
using namespace std;

typedef long long ll;
const int maxn = 2e5 + 6;
ll n, m, a[maxn], c[maxn], ans;
set<int> s;

int main() {
cin >> n >> m;

for(int i = 0; i < m; i++) {	//将所有可能的余数压入集合
s.insert(i);
}

for(int i = 0; i < n; i++) {
cin >> a[i];
int d = a[i] % m, x;

if(d > *s.rbegin() ) {
x = *s.begin();	//如果 大于最大的，则最近的是第一个
}else {
x = *s.lower_bound(d);		//找到大于等于d的第一个余数
}

if(++c[x] == n / m) s.erase(x);		//如果此时已经等于n/m之后，则再集合中删除x，
//即保证了余数为x这种情况不会再有更多的数
ans += (x - d + m) % m;
a[i] += (x - d + m) % m;
}

cout << ans << endl;
for(int i = 0; i < n; i++)  i == n - 1 ? cout << a[i] << "\n" : cout << a[i] << " ";
return 0;
} 

06-28 21

07-24 170

06-24 698

06-22 554

07-09 76

04-09 2445

05-01 1077

11-08 10

08-08 75

08-08 67

06-23 363

08-23 6

05-15 37

07-27 91

08-08 133

08-03 58

07-01 99

07-12 16

07-30 122

07-09 185

07-19 51

04-14 56万+

03-13 14万+

02-27 7万+

02-28 4万+

03-01 12万+

03-01 11万+

03-01 1万+

03-03 2万+

05-23 4017

03-04 12万+

03-04 3403

03-05 5万+

03-08 4万+

03-08 6万+

03-08 2万+

03-08 1万+

04-25 6万+

03-10 12万+

03-10 17万+

03-12 10万+

03-13 10万+

03-19 7万+

03-22 3万+

03-23 1万+

03-23 4万+

03-24 3万+

03-25 2万+

05-08 4万+

03-25 8万+

03-26 3万+

03-27 4万+

03-29 20万+

03-29 9万+

03-30 14万+

05-21 2936

05-25 5229

03-23 1万+

04-02 3万+

05-06 2万+

04-05 1万+

04-06 899

04-06 6万+

04-07 4万+

04-09 7万+

04-09 2万+

05-17 5342

04-09 4723

04-11 2万+

04-15 5万+

04-18 4万+

04-20 3万+

04-24 2万+

04-26 3680

04-30 7538

05-16 4万+

05-06 1万+

05-08 3万+

05-11 3万+

#### 优秀的程序员真的不写注释吗？

©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试