CF1416B Make Them Equal
注意到以下几个性质:
1、总和始终不变。
2、变化量跟 \(i\) 有关,当 \(i = 1\) 时变化量随意。
因此我们围绕 \(i = 1\) 来操作。操作分下面三步:
对于 \(i \in [2, n]\),
1、令 \(a_i = ki\)
2、令 \(a_i = 0\)
3、令 \(a_i = \frac{\sum{sum}}{n}\)
下面证明一下在 \(a_i \ge 0\) 的情况下 \(1,2\) 为什么总是能合法执行:
对于 \(\forall i \in [2, n],a_i \mod i \le i - 1\),
又因为 \(a_i \ge 1\),所以 \(sum_{i - 1} \ge i - 1\),所以做到 \(i\) 的时候 \(a_1\) 一定是够的。
证毕。
总次数 \(3(n - 1)\),符合要求。
#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l); i <= (r); ++ i)
#define G(i,r,l) for(int i(r); i >= (l); -- i)
using namespace std;
using ll = long long;
const int N = 2e4;
struct node{
int i, j, x;
}ans[N * 3];
int a[N];
int n, T;
void Main(){
int k = 0, s = 0;
cin >> n;
F(i, 1, n){
cin >> a[i];
s += a[i];
}
if(s % n != 0){
cout << -1 << '\n';
return ;
}
int xa = s / n;
F(i, 2, n){
if(a[i] % i != 0){
int tmp = i - a[i] % i;
ans[++ k] = (node){1, i, tmp};
a[i] += tmp;
a[1] -= tmp;
}
ans[++ k] = (node){i, 1, a[i] / i};
a[1] += a[i];
a[i] = 0;
}
F(i, 2, n){
ans[++ k] = (node){1, i, xa};
}
cout << k << '\n';
F(i, 1, k){
cout << ans[i].i << ' ' << ans[i].j << ' ' << ans[i].x << '\n';
}
return ;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> T;
while(T --) Main();
return fflush(0), 0;
}
从余数角度考虑这个问题是关键。应该大胆猜操作然后再尽可能用数学知识去假设、去验证。

浙公网安备 33010602011771号