D. Make Them Equal(思维)
思维。
思路:显然每次操作所有数之和 s u m sum sum是不变的,首先特判平均值是否存在。然后考虑将所有和先聚集到 a [ 1 ] a[1] a[1]上,在依次分给 a [ 2 ] − a [ n ] a[2]-a[n] a[2]−a[n]。
如果 a [ i ] ( m o d i ) = 0 a[i]\pmod{i}=0 a[i](modi)=0,显然可以将 a [ i ] a[i] a[i]加到 a [ 1 ] a[1] a[1]上,然后 a [ i ] = 0 a[i]=0 a[i]=0。
否则,就先让 a [ i ] a[i] a[i]减去 i − a [ i ] ( m o d i ) i-a[i]\pmod{i} i−a[i](modi),这样就能整除。
这样的正确性:因为 a [ i ] ( m o d i ) > 0 a[i]\pmod{i}>0 a[i](modi)>0, i − a [ i ] ( m o d i ) < i i-a[i]\pmod{i}<i i−a[i](modi)<i
每轮 a [ 1 ] a[1] a[1]都至少加 1 1 1,所以第 i i i轮 a [ 1 ] ≥ i a[1]\geq i a[1]≥i,所以 a [ 1 ] a[1] a[1]不会为负。
这样操作最多: 3 ( n − 1 ) 3(n-1) 3(n−1)次。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e4+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
#define il inline
int t,n;
int a[N];
vector<array<int,3> >ans;
void fun(int x,int y,int z){
a[x]-=x*z,a[y]+=x*z;
ans.pb({x,y,z});
}
int main(){
scanf("%d",&t);
while(t--){
int sum=0;
scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i];
if(sum%n) puts("-1");
else {
ans.clear();
for(int i=2;i<=n;i++){
if(a[i]%i) fun(1,i,i-a[i]%i);
fun(i,1,a[i]/i);
}
for(int i=2;i<=n;i++) fun(1,i,sum/n);
printf("%d\n",ans.size());
for(auto i:ans) printf("%d %d %d\n",i[0],i[1],i[2]);
}
}
return 0;
}