日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Equalize the Remainders(set二分+思维)

發布時間:2023/12/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Equalize the Remainders(set二分+思维) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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
6 3
3 2 0 6 10 12
Output
3
3 2 0 7 10 14
Input
4 2
0 1 2 3
Output
0
0 1 2 3
題意:構造出這樣的一組序列,使得這個數組中的每個數字取模m之后的數字即0~m-1都出現過n/m次。問最少需要操作多少次。
思路:對于余數出現次數少于n/m次的數,我們放到set中去。
對于出現次數多于n/m的數,我們二分去找set中第一個大于這個數的數。如果操作之后這個數的出現次數等于n/m次了,就將之從集合中刪除。
代碼如下:

#include<bits/stdc++.h> #define ll long long using namespace std;const int maxx=2e5+100; ll a[maxx]; int b[maxx]; int n,m;int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) {scanf("%I64d",&a[i]);b[a[i]%m]++;}set<ll> s;for(int i=0;i<m;i++){if(b[i]<n/m) s.insert(i);}ll ans=0;for(int i=1;i<=n;i++){if(b[a[i]%m]<=n/m) continue;b[a[i]%m]--;set<ll> ::iterator it=s.lower_bound(a[i]%m);if(it!=s.end())//找到了{ans+=*it-a[i]%m;a[i]+=*it-a[i]%m;b[*it]++;if(b[*it]==n/m) s.erase(it);}else//沒有找到的話,就要變成集合中的第一個元素。{ans+=(*s.begin()+m-a[i]%m)%m;a[i]+=(*s.begin()+m-a[i]%m)%m;b[*s.begin()]++;if(b[*s.begin()]==n/m) s.erase(s.begin());} }cout<<ans<<endl;for(int i=1;i<=n;i++) cout<<a[i]<<" ";cout<<endl; }

努力加油a啊,(o)/~

總結

以上是生活随笔為你收集整理的Equalize the Remainders(set二分+思维)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。