zhao_ry514114
赵若伊

导航

 

思路

我们需要构造 \(W_1,W_2,\dots,W_N\),使得 \(\sum A_iW_i>\sum B_iW_i\)。

移项后等价于 \(\sum (A_i-B_i)W_i>0\)。

所以只需要考虑每一项的差 \(A_i-B_i\)。

如果存在某个位置满足 \(A_i>B_i\),那么这一项对答案有正贡献。

此时可以直接把这个位置的权值设得非常大,例如 \(10^{18}\),而其余位置全部设为 \(1\)。

这样正贡献会被放大到足以压过其他位置的负贡献。

因为对于任意位置都有 \(|A_i-B_i|\le 10^9\),并且 \(N\le 10^5\),所以其余所有位置造成的负贡献绝对值之和最多约为 \(10^{14}\)。

而只要存在一个 \(A_i>B_i\),把它的权值设为 \(10^{18}\),这一项至少可以产生 \(10^{18}\) 的正贡献,显然大于其他所有负贡献之和。

因此,只要存在 \(A_i>B_i\),就一定有解。

如果对于所有位置都有 \(A_i\le B_i\),那么对于任意正整数 \(W_i\) 都有 \((A_i-B_i)W_i\le 0\)。

所以 \(\sum (A_i-B_i)W_i\le0\),不可能严格大于 \(0\),因此无解。

于是结论非常简单:

  • 如果存在 \(A_i>B_i\),输出 Yes;
  • 对这些满足 \(A_i>B_i\) 的位置令 \(W_i=10^{18}\);
  • 其他位置令 \(W_i=1\);
  • 如果不存在任何 \(A_i>B_i\),输出 No。

如何想到的

看到要求 \(\sum A_iW_i>\sum B_iW_i\) 以后,可以先移项成 \(\sum (A_i-B_i)W_i>0\)。

因为 \(W_i\) 是可以自由构造的,而且上界非常大,所以自然会想到:如果某一项的系数 \(A_i-B_i\) 是正数,就把这一项的权值尽量放大;如果系数不是正数,就让它的权值尽量小。

因此对于 \(A_i>B_i\) 的位置设成 \(10^{18}\),其余位置设成 \(1\)。

接下来只需要确认 \(10^{18}\) 是否足够大。其他所有位置的负贡献总和最多只有 \(10^5\times10^9=10^{14}\),而一个正位置就至少能贡献 \(10^{18}\),所以一定可以压过去。

这样就得到了这个非常直接的构造。

代码

#include <bits/stdc++.h>
#define rep(i,j,k) for (int i = (j); i <= (k); i ++)
#define per(i,j,k) for (int i = (j); i >= (k); i --)
#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define db double
#define ldb long double
#define mkp make_pair
#define eb emplace_back
#define e_ emplace
#define ls (p << 1)
#define rs (p << 1 | 1)
//#define int ll
using namespace std;
const int N = 1e5 + 5;
//const int MOD = 998244353;
//const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;
const ll LINF = 4e18;
//int T;
int n;
int a[N], b[N];

signed main () {
    //freopen (".in", "r", stdin);
    //freopen (".out", "w", stdout);
    ios::sync_with_stdio (0);
    cin.tie (0);
    cin >> n;
    bool x = false;
    string ans;
    rep (i, 1, n) cin >> a[i];
    rep (i, 1, n) {
        cin >> b[i];
        if (a[i] > b[i]) {
            ans += "1000000000000000000 ";
            x = true;
        }
        else ans += "1 ";
    }
    if (x) cout << "Yes\n" << ans;
    else cout << "No";
    return 0;
}

复杂度

时间复杂度为 \(O(N)\)。

posted on 2026-09-11 19:13  zhao_ry514114  阅读(13)  评论(0)    收藏  举报