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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值