http://codeforces.com/contest/1111/problem/C
题目挺巧的,这样分支,最多有1e5个(k的上界),所以可以过。
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
LL n,k,A,B;
LL a[100005];
LL counta(LL l,LL r){
LL x=lower_bound(a+1,a+1+k,l)-a;
LL y=upper_bound(a+1,a+1+k,r)-a;
return y-x;
}
LL dfs(LL l,LL r){
LL kk=counta(l,r);
if(kk==0) return A;
if(l==r) return B*kk;
LL mid=(l+r)/2;
return min(dfs(l,mid)+dfs(mid+1,r),kk*B*(r-l+1));
}
int main(){
cin>>n>>k>>A>>B;
for(int i=1;i<=k;i++){
scanf("%lld",&a[i]);
}
sort(a+1,a+1+k);
cout<<dfs(1,1<<n);
return 0;
}