CF1416B Make Them Equal

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;
}

从余数角度考虑这个问题是关键。应该大胆猜操作然后再尽可能用数学知识去假设、去验证。

posted @ 2026-09-04 15:12  superl61  阅读(2)  评论(0)    收藏  举报