CF1111C Creative Snap

思路:

分治,递归实现就可以。不一定非得用前缀和,直接用一个数组记录avengers的位置然后二分即可。写的有点复杂了。

实现:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll n, k, A, B;
 5 ll dfs(ll l, ll r, vector<ll>& K, vector<ll>& V, vector<ll>& S)
 6 {
 7     if (l == r)
 8     {
 9         if (binary_search(K.begin(), K.end(), l))
10         {
11             int p = lower_bound(K.begin(), K.end(), l) - K.begin();
12             return B * V[p];
13         }
14         return A;
15     }
16     int p1 = lower_bound(K.begin(), K.end(), l) - K.begin();
17     int p2 = upper_bound(K.begin(), K.end(), r) - K.begin() - 1;
18     if (p1 > p2) return A;
19     ll minn = B * (S[p2] - S[p1 - 1]) * (r - l + 1);
20     ll m = l + r >> 1;
21     minn = min(minn, dfs(l, m, K, V, S) + dfs(m + 1, r, K, V, S));
22     return minn;
23 }
24 int main()
25 {
26     while (cin >> n >> k >> A >> B)
27     {
28         map<ll, ll> mp;
29         int x;
30         for (int i = 1; i <= k; i++)
31         {
32             cin >> x;
33             if (!mp.count(x)) mp[x] = 0;
34             mp[x]++;
35         }
36         vector<ll> K, V, S;
37         K.push_back(0); V.push_back(0); S.push_back(0);
38         for (auto it: mp) { K.push_back(it.first); V.push_back(it.second); }
39         for (int i = 1; i < V.size(); i++) S.push_back(S.back() + V[i]);
40         cout << dfs(1, 1 << n, K, V, S) << endl;        
41     }    
42     return 0;
43 }

猜你喜欢

转载自www.cnblogs.com/wangyiming/p/10352445.html
今日推荐