*题解:CF1979C Earning on Bets
解析
由题意得,约束条件即为 \(\forall 1\le i\le n, sum < k_i a_i\),其中 \(sum=\sum_{i=1}^n a_i\)。把 \(k\) 除过去,变为 \(\frac{sum}{k_i}<a_i\),求和变为 \(\sum_{i=1}^n \frac{sum}{k_i}<sum\)。两边同除 \(sum\) 变为 \(\sum_{i=1}^n \frac{1}{k_i}<1\),此为原命题的必要条件,不满足必定无解。
考虑如果满足该条件如何构造出一组解。令 \(a_i=\frac{1}{k_i}\),则 \(sum = \sum_{i=1}^n \frac{1}{k_i} < 1 = k_ia_i\),充分性得证。为了使 \(a_i\) 变为整数,我们还需要将每个 \(a_i\) 乘上所有 \(k_i\) 的最小公倍数。
时间复杂度 \(O(n)\)。
代码
#include <bits/stdc++.h>
#define eps 0.0000000001
#define ls(x) ((x) << 1)
#define rs(x) (((x) << 1) | 1)
//#define mid ((l + r) >> 1)
using namespace std;
typedef long long ll;
typedef unsigned ui;
typedef pair<int,ll> pii;
const int N = 2e5 + 5,M = 10000 + 5,P = 2000000,mod = 1e9 + 7,mod2 = 1e9 + 7,b1 = 131,b2 = 13331;
int k[N];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
// freopen("in.txt","r",stdin);
// freopen("out1.txt","w",stdout);
int T;
cin>>T;
while(T--){
int n;
cin>>n;
int l = 1;
double sum = 0;
for(int i=1;i<=n;i++){
cin>>k[i];
l = l / __gcd(k[i],l) * k[i];
sum += 1.0 / k[i];
}
if(sum > 1 || fabs(sum - 1) < eps){
cout<<-1<<'\n';
continue;
}
for(int i=1;i<=n;i++){
cout<<l / k[i]<<" ";
}
cout<<'\n';
}
return 0;
}

浙公网安备 33010602011771号