1 条题解

  • 0
    @ 2025-10-22 11:10:29
    • 折半搜索
    • 将前一半和后一半数分别做暴力,将结果分别存到 vector
    • 然后枚举其中一个 vector,在另一个 vector 中做二分
    #include <bits/stdc++.h>
    using namespace std;
    
    using i64 = long long;
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        
        i64 n, m;
        cin >> n >> m;
        vector<i64> a(n);
        for (int i = 0; i < n; i++) cin >> a[i];
        
        vector<vector<i64>> h(2);
        function<void(int, int, i64, int)> dfs = [&](int p, int r, i64 s, int f) {
            // 第 1 步: 终止条件
            if (p == r) {
                h[f].push_back(s);
                return ;
            }
            
            // 第 2 步: 转移问题
            dfs(p + 1, r, s, f);         // 不要 a[p]
            dfs(p + 1, r, s + a[p], f);  // 要 a[p]
            
        };
        
        int mid = n / 2;
        dfs(0, mid, 0, 0);  // [0, mid) 的结果放在 h[0]
        dfs(mid, n, 0, 1);  // [mid, n) 的结果放在 h[1]
        
        i64 ans = 0;
        sort(h[1].begin(), h[1].end());
        for (i64 x : h[0]) {
            ans += upper_bound(h[1].begin(), h[1].end(), m - x) - h[1].begin();
        }
        cout << ans << '\n';
    
        return 0;
    }
    
    • 1

    [CEOI 2015] 世界冰球锦标赛 (Day2)

    信息

    ID
    154
    时间
    1000ms
    内存
    500MiB
    难度
    7
    标签
    递交数
    32
    已通过
    10
    上传者