D. Divide and Summarize(递归、分治)

D. Divide and Summarize

和二叉树的遍历形式差不多,往左右两棵子树不断递归。

不过这道题要在往下递归的途中不断进行找中间数以及求和。

另外可以用map来保存一个值是否出现过。

#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

typedef long long LL;
const int N = 1e5 + 10;
map<LL, int> mp;
LL n, m, a[N], sum[N];

void solve(int l, int r){
    if(l < 1 || r > n || l > r)
        return;
    if(a[l] == a[r]){
        mp[a[l] * (r - l + 1)] = 1;
        return;
    }
    LL mid = a[l] + a[r] >> 1;
    LL pos = upper_bound(a + l, a + r + 1, mid) - a - 1;
    if(pos)
        mp[sum[pos] - sum[l - 1]] = 1;
    mp[sum[r] - sum[pos]] = 1;
    solve(l, pos);
    solve(pos + 1, r);
    
}
int main(){
    int t;
    cin >> t;
    while(t --){
        mp.clear(); 
        cin >> n >> m;
        for(int i = 1; i <= n; i ++)
            cin >> a[i];
        sort(a + 1, a + 1 + n);
        for(int i = 1; i <= n; i ++)
            sum[i] = sum[i - 1] + a[i];
        solve(1, n);
        mp[sum[n]] = 1;
        while(m --){
            LL temp;
            cin >> temp;
            if(mp[temp] == 1)
                cout << "Yes" << endl;
            else
                cout << "No" << endl;
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/pureayu/p/14152351.html