D.Make Them Equal

        Codeforces Round #673 (Div. 2)——D. Make Them Equal

2020/9/28
Facts have proved that this question is really simple. Compared with the complicated processing of question C, I think this question is simpler. Pure thinking questions, but I still did not write the
title:
You are given an array a consisting of n positive integers, numbered from 1 to n. You can perform the following operation no more than 3n times:

choose three integers i, j and x (1≤i,j≤n; 0≤x≤109);
assign ai:=ai−x⋅i, aj:=aj+x⋅i.
After each operation, all elements of the array should be non-negative.

Can you find a sequence of no more than 3n operations after which all elements of the array are equal?
Question meaning:
Given an array of n positive integers, you can perform one operation at a time:
choose three numbers i, j, x, then ai=ai+i*x, aj=aj+j*x, the analysis is to choose a position i to make it a number that is reduced by i, and add this number to any position.
Can the number of n be made the same within 3*n operations?
Analysis:
Analyze the formula first, we can know that if the number ai at the position i is a multiple of i, the number at that position can be taken away by all i i. It is obvious that for the number at the first position, it is Absolutely excellent, because it can be allocated by any multiple of 1 (that is, any number).
For the impossible situation: if and only if the sum of n numbers is not a multiple of n, there is no solution, the situation is obvious, but why only this situation is unsolvable — here is a construction process:
 rep i ,2,n
  For ai, is it a multiple of i?
   If it is, then directly move ai to a1 according to i=i,j=1,x=ai/i.
   If not, then directly a1 according to i = 1, j = i, x = i-ai% i, the number a1 moved ai, ai such that is a multiple of the number i, and then the same reason the number of all moved ai a1.
   - ---Why can it be determined that it can be moved here, because at the beginning a1>=1, and 2-a2<=1 (because only a2 is not a multiple of 2), and then the value of a1+=a2, continue to push to find no matter the array a What is the value of, can satisfy the order of i from 2 to n, for i there must be a1>=i-1, and i-ai<=i-1 ie i-ai<=a1, so each round a1 There are enough numbers allocated to ai so that ai is a multiple of i.
At this point, we can find that no matter what the situation (except the -1 situation at the beginning), all the values ​​from a2 to an can be transferred to a1 (that is, both a2 and an are changed under <=2*(n-1) operations. Into 0). After that, it only takes n-1 operations to assign the value of a1 to a2 to an by the average number one by one (because the position of a1 can be assigned any number)
code:

#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define mp make_pair
#define pb push_back
#define G 6.67430*1e-11
#define  rd read()
#define pi 3.1415926535
using namespace std;
const ll mod = 998244353;
inline ll read() {
    
    
    ll x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch>'9') {
    
    
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
    
    
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}
ll fpow(ll a, ll b)
{
    
    
    ll ans = 1;
    while (b)
    {
    
    
        if (b & 1)ans = ans * a % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return ans;
}
ll gcd(ll a, ll b) {
    
     return !b ? a : gcd(b, a % b); }
const int N = 1000010;


bool isprime(int n)
{
    
    
    for (int i = 2; i <= sqrt(n); i++)if (n % i == 0)return false;
    return true;
}ll jc[300005];
ll x[10005];
struct s {
    
     ll a, b, c; };
vector<s> v;
priority_queue<pll> p;
int main()
{
    
    
    int t = rd;
    while (t--)
    {
    
    
        v.clear();
        int n = rd;
        ll sum = 0;
        for (int i = 1; i <= n; i++)
        {
    
    
            x[i] = rd;
            sum += x[i];
        }
        if (sum % n == 0)
        {
    
    
            sum /= n;
        }
        else
        {
    
    
            cout << -1 << endl;
            continue;
        }
        int f = 0;
        for (int i = 2; i <= n; i++)
        {
    
    
            if (x[i] % i)
            {
    
    
                struct s a = {
    
     1, i, i - x[i] % i };
                v.push_back(a);
                x[i] += i - x[i] % i;
                a = {
    
     i, 1, x[i] / i };
                v.push_back(a);
            }
            else
            {
    
    
                s a = {
    
     i, 1, x[i] / i };
                v.push_back(a);
            }
        }
        for (int i = 2; i <= n; i++)
        {
    
    
            struct s a = {
    
     1, i, sum};
            v.push_back(a);
        }
        cout << v.size() << endl;
        for (auto p : v)
        {
    
    
            cout << p.a << ' ' << p.b << ' ' << p.c << endl;
        }
    }
    return 0;
}
//cout << (97 * 4 + 95 + 95 * 3 + 88 + 88 * 4 + 87 * 3.5  + 80 * 0.25)/( 4 + 1 + 3 + 1 + 4 + 3.5  + 0.25 );

Guess you like

Origin blog.csdn.net/ylwhxht/article/details/108841615