1 条题解

  • 0
    @ 2026-11-1 19:56:14

    [NICA #3] 星空(Easy Version)(Starry Sky Easy) 题解

    思路分析

    将互不相同的 22 的幂升序排列为 a1<a2<⋯<ana_1 < a_2 < \dots < a_n。利用 22 的幂的性质:除最大值 ana_n 外的任意两数之和满足 au+av≤an−2+an−1<ana_u + a_v \le a_{n-2} + a_{n-1} < a_n!

    • 若 an>xa_n > x,由于 n≥2n \ge 2,ana_n 必有相邻元素,和必 >x> x,答案为 00;
    • 若 an≤xa_n \le x,则除 ana_n 以外的任意两个元素相邻都必定合法(≤x\le x)!唯一需要满足的约束是「与最大值 ana_n 相邻的元素必须属于集合 S={j<n:an+aj≤x}S = \{j < n : a_n + a_j \le x\}」。设 s=∣S∣s = |S|:
      • ana_n 放在首尾两端(22 个位置):有 11 个邻居选自 SS,其余 n−2n - 2 个元素任意排,共 2s(n−2)!2s(n - 2)! 种;
      • ana_n 放在中间(n−2n - 2 个位置):左右 22 个邻居有序选自 SS,其余 n−3n - 3 个元素任意排,共 (n−2)s(s−1)(n−3)!=s(s−1)(n−2)!(n - 2)s(s - 1)(n - 3)! = s(s - 1)(n - 2)! 种。 两者相加化简得总方案数为 s(s+1)(n−2)! mod (109+7)s(s + 1)(n - 2)! \bmod (10^9 + 7)。时间复杂度 O(nlog⁡n)O(n \log n)。

    参考代码

    #include <algorithm>
    #include <iostream>
    using namespace std;
    
    const long long MOD = 1000000007LL;
    unsigned long long a[70];
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n;
        unsigned long long x;
        if (!(cin >> n >> x)) return 0;
        for (int i = 0; i < n; ++i) cin >> a[i];
        sort(a, a + n);
    
        long long s = 0;
        for (int i = 0; i < n - 1; ++i)
        {
            if (a[n - 1] + a[i] <= x) ++s;
        }
        long long fact = 1;
        for (int i = 1; i <= n - 2; ++i) fact = (fact * i) % MOD;
        long long ans = s * (s + 1) % MOD * fact % MOD;
        cout << ans << "\n";
        return 0;
    }
    
    • 1

    [NICA #3] 星空(Easy Version)(Starry Sky Easy)

    信息

    ID
    8565
    时间
    1000ms
    内存
    512MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者