zoukankan      html  css  js  c++  java
  • CodeForces-999D Equalize the Remainders

    题目链接

    https://vjudge.net/problem/CodeForces-999D

    题面

    Description

    You are given an array consisting of n integers a1,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 i between 1 and n and increase ai by 1.

    Let's calculate cr (0≤r≤m−1) — the number of elements having remainder r when divided by m. 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=(frac{n}m).

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

    Input

    The first line of input contains two integers n and m (1≤n≤2⋅105,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≤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 0 to m−1, the number of elements of the array having this remainder equals (frac{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}).

    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 
    

    题解

    当初比赛中做麻烦,直接写正解吧

    用set维护现在个数还不够(frac{n}{m})的余数,然后从1到n循环,计算a[i]的余数,找到set中第一个大于等于这个余数的余数,把这个数的余数补成它,如果没有大于大于等于的,就找到set中的第一个数,这样每个余数不足的都由离他最近的数补成,从而使操作次数最小,用一个change数组记录每个数变化了多少,最后输出a[i]+change[i]即可

    #include<bits/stdc++.h>
    #define N 200050
    using namespace std;
    typedef long long ll;
    int a[N];
    int cnt[N];
    int change[N];
    int main() {
    	int n, m;
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++) {
    		scanf("%d", &a[i]);
    	}
    	ll ans = 0;
    	set<int> s;
    	for (int i = 0; i < m; i++) {
    		s.insert(i);
    	}
    	for (int i = 1; i <= n; i++) {
    		int tmp = a[i] % m;
    		int x = tmp > *s.rbegin() ? *s.begin() : *s.lower_bound(tmp);
    		cnt[x]++;
    		if (cnt[x] == n / m) s.erase(x);
    		ans += (x - tmp + m) % m;
    		change[i] += (x - tmp + m) % m;
    	}
    	printf("%lld
    ", ans);
    	for (int i = 1; i <= n; i++) {
    		printf("%d ", a[i] + change[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    poj 2352 Stars(线段树)
    poj 2029 Get Many Persimmon Trees
    .Net remoting 的解答,以及跟WebService的区别
    关于Xcode4.2中的release“不能”使用的理解
    委托的学习日志
    钩子是啥?以及用来说啥,是不是可以用来做即时通讯?
    C#后台程序与HTML页面中JS方法互调(功能类似于Ajax中的DWR)
    接触了一下项目管理系统软件:禅道项目管理软件、Bugfree
    将string变为int 的几种方法方法比较
    Hashtable、Dictionary、SortedDictionary、SortedList的比较应用
  • 原文地址:https://www.cnblogs.com/artoriax/p/10384948.html
Copyright © 2011-2022 走看看