Codeforces Round #673 (Div. 2) D. Make Them Equal ( 构造 ) + E. XOR Inverse (字典树)

链接: D. Make Them Equal

题意:
给一个长度为 n 的数组 , 每次操作 可以选择一个 i , j , k ,使ai = ai − x ⋅ i , aj : = aj + x ⋅ i。求最多 3 * n 次操作内使每个数都相等的操作方法 ,操作过程每个数都不能变为负数。

思路:

  1. 首先我们可以发现 对于 a[i] 这个数,我们可以给数组中的其他任何一个数加上任意的值 ,前提是 a[i] 足够大。所以我们可以先把其他的数都加到 a[1] 上去 , 再把它分配给其他的数。
  2. 怎么把后面的值都分给 a[1] 呢 , 如果 a[i] % i == 0,可以直接分配 ,如果不等于 0 ,我们可以先用 a[i] 给它加上 一定的值使它能被 i 整除(这时 a[i] ,一定是够的 因为每个数至少为 1 ,你在给第i位补数时 ,前 i-1 位都已经转移到 a[1] 了)。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 4e6 + 7;
int T,n,a[maxn],sum,ave,ans;
int main(){
    
    
    scanf("%d",&T);
    while(T--){
    
    
        scanf("%d",&n);
        sum = ans = 0;
        for(int i = 1; i <= n ; i ++){
    
    
            scanf("%d",&a[i]);
            sum += a[i];
            if(a[i] % i) ans ++;
        }
        if(sum % n != 0){
    
    
            printf ("-1\n");
            continue;
        }
        ave = sum / n;
        printf ("%d\n",2 * (n - 1) + ans);
        for(int i = 2; i <= n; i ++){
    
    
            if(a[i] % i == 0){
    
    
                printf ("%d 1 %d\n",i , a[i] / i);
            }
            else{
    
    
                printf ("1 %d %d\n",i,i - a[i] % i);
                printf ("%d 1 %d\n",i,a[i] / i + 1);
            }
        }
        for(int i = 2; i <= n; i ++){
    
    
            printf ("1 %d %d\n",i,ave);
        }
    }
}

E题题解 :E. XOR Inverse

猜你喜欢

转载自blog.csdn.net/hddddh/article/details/108849607