D. Make Them Equal 构造
构造题真的就是想到好写,不过基本想不到,本题想到了就稍微记录一下(题意和思路都在代码块内)
D. Make Them Equal
//https://codeforces.com/contest/1417/problem/D
//长度为n的序列,在操作次数不超过3*n的情况下,使得所有元素值相等,可以则输出方案,否则输出-1
//同时每次操作后不能有元素为非负数
//单次操作:选择一个三元组{i,j,x} a[i]=a[i]-x*i a[j]=a[j]+x*i
//显然,如果sum%n!=0,一定不可以
//构造方案:
//第一步:从2开始for一遍,每次将其所有数都转移给1。
//①若a[pos]%pos==0,可以直接转给1 ,操作:{pos,1,a[pos]/pos}
//②若a[pos]%pos!=0,那么1<=a[pos]%pos<pos,要是的a[pos]%pos==0,可以(a[pos]+x)%pos,即给a[pos]加上一个数x
// 数据保证了初始1<=a[i]<=1e5,则前pos-1个数的总和>=pos-1,可以满足任意a[pos]所需的任意x。
// 即先位置1给位置pos数x,在全部转给1 操作:{1,pos,(i-a[pos]%pos)},{pos,1,(a[pos]+(i-a[pos]%pos))/i}
//第二步:此时全部的数都在位置1,再从2开始for一遍,每次从位置1转给位置i数sum/n, 操作:{1,i,sum/n};
//第一步操作次数最多2*(n-1),第二步操作次数n-1,总操作次数最多3*(n-1)<3*n
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N];
struct node{int st,ed,x;};
vector<node>ans;
vector<pair<int,int> >hh;
void solve(){
ans.clear(),hh.clear();
int sum=0;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i];
if(sum%n!=0){puts("-1");return;}
int ned=sum/n;
for(int i=2;i<=n;i++){
int yu=a[i]%i;
if(yu==0) ans.push_back({i,1,a[i]/i});
else{
ans.push_back({1,i,i-yu});
ans.push_back({i,1,(a[i]+i-yu)/i});
}
}
for(int i=2;i<=n;i++) ans.push_back({1,i,ned});
int len=ans.size();
printf("%d\n",len);
for(int i=0;i<len;i++) printf("%d %d %d\n",ans[i].st,ans[i].ed,ans[i].x);
}
int main(){
int t;scanf("%d",&t);
while(t--) solve();
}