CF1416B Make Them Equal

首先观察到每次操作不会改变整个数组的和 sum,所以最终整个数组都会变成平均数

因此如果sum不是n的倍数 则无解

由于没观察到这个点导致我被卡的死死的

其次就是当选择(1, i, x)这个三元组的时候,可以对任意的 x>=a[1],a[1]-=x,a[i]+=x, 这就使每次加减的数不受是"某个除1以外的数的倍数"的限制

所以接下来的想法是把a[2]~a[n]都加到a[1]上,然后再由a[1]分配到这些位置上

由于a[i]只能减去i的倍数的数所以可分为两种情况

1.a[i]是i的倍数

2.a[i]不是i的倍数

对于情况1 可以直接把a[i]加到a[1]上,记为1次操作

而对于情况2 则需要从a[1]“借”来一些数,让a[i]变为i的倍数

具体操作为: a[1]-=i-a[i]%i a[i]+=i-a[i]%i,然后当情况1处理,这就记为2次操作

在这里可以看到a[1]有变为负数的可能,其实可以证明a[1]在操作过程中始终不为负数,证明如下:

当处理到a[i]时 此时a[1]等于前i-1项的和,因为数组的数大于等于1,则a[1]>=i-1,而i-a[i]%i<=i-1,所以a[1]始终>=0

最后“a[2]~a[n]都加到a[1]上”这个操作最多有2*(n-1)次,a[1]进行分配需要操作n-1次,总操作数不超过3*(n-1)次 符合题目要求

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define db double
#define rep(x,a,b) for(int x=(a);x<=(b);x++)
#define per(x,a,b) for(int x=(a);x>=(b);x--)
#define scf(a) scanf("%d",&a)
#define scfll(a) scanf("%lld",&a)
#define scfdb(a) scanf("%lf",&a)
#define ptf(a) printf("%d",a)
#define ptfll(a) printf("%lld",a)
#define ptfdb(x,a) printf("%x.lf",a)
#define ptfsp(a) printf("%d ",a)
#define ptfllsp(a) printf("%lld ",a)
#define ptfdbsp(x,a) printf("%x.lf ",a)
#define pli(a,b) make_pair(a,b)
#define pb push_back
#define el puts("")
#define pi 3.1415926
using namespace std;
const int maxn=2e5+5;
const ll mod=1e9+7;
struct node{
    int i,j,val;
}ans[maxn];
int a[maxn];
int main(){
    int T;scf(T);
    while(T--){
        int n;scf(n);
        int sum=0;
        rep(i,1,n) scf(a[i]),sum+=a[i];
        if(sum%n!=0){
            puts("-1");
            continue;
        }
        int cnt=0;
        rep(i,2,n){
            if(a[i]%i){
                ans[++cnt]=(node){1,i,i-a[i]%i};
                a[1]-=i-a[i]%i;
                a[i]+=i-a[i]%i;
            }
            ans[++cnt]=(node){i,1,a[i]/i};
            a[1]+=a[i];
            a[i]=0;
        }
        rep(i,2,n)
            ans[++cnt]=(node){1,i,sum/n};
        ptf(cnt);el;
        rep(i,1,cnt)
            ptfsp(ans[i].i),ptfsp(ans[i].j),ptfsp(ans[i].val),el;
    }
}


 

猜你喜欢

转载自blog.csdn.net/ghu99999/article/details/115006662