题目大意:

给定n k A B为位置长度 复仇者个数 两种花费

在一段为1~2^n的位置中 某些位置存在一些复仇者

求消灭所有复仇者的最小花费

对一段位置可以有两种处理方式

1.若该段长度至少为2 可以将其分成长度相等的两段分开处理

2.若该段中不存在复仇者 那么一共只需花费 A

若该段中存在复仇者 那么花费为 复仇者个数*该段长度*B

将复仇者位置排序后 对范围[l,r]的一段 利用二分函数就可获得该段中复仇者的个数

对整段[1,2^n]深搜一下 复杂度不超过O((2^n)<<2)

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define mem(i,j) memset(i,j,sizeof(i))
const int N=1e5+;
LL n,k,A,B,a[N];
LL dfs(int l,int r) {
int L=lower_bound(a,a+k,l)-a;
int R=upper_bound(a,a+k,r)-a;
LL cnt=R-L; // 在l r范围内的复仇者的个数
if(cnt==) return A; // 没有复仇者
if(l==r) return B*cnt; // 已经缩小到一个点 且该点有复仇者
int m=(l+r)>>; // 将当前段二分
return min(B*cnt*(r-l+),dfs(l,m)+dfs(m+,r));
// 直接消灭整段的复仇者 和 二分后再消灭 取小
}
int main()
{
while(~scanf("%I64d%I64d%I64d%I64d",&n,&k,&A,&B)) {
for(int i=;i<k;i++) scanf("%I64d",&a[i]);
sort(a,a+k); // 将所有复仇者的位置排序 然后才可用二分函数
printf("%I64d\n",dfs(,<<n));
} return ;
}

最新文章

  1. JS中的对象
  2. Linux查看系统运行情况
  3. JavaScript之命名空间模式 浅析
  4. java--UDP屏幕广播代码
  5. java 如何在pdf中生成表格
  6. cach
  7. Android 在内部存储读写文件
  8. 记录sqoop同步失败问题解决过程,过程真的是很崎岖。(1月6日解决)
  9. [摘录]quarts :overview
  10. ASP.NET 项目 App_Code下无法找到类
  11. undrop for innodb c_parser 源码分析
  12. SQL server抽疯后修改sa密码无法成功的处理办法
  13. 【转】 Linux/Unix 进程间通信的各种方式及其比较
  14. Delphi 2007体验!
  15. 非常详细的 Docker 学习笔记-转载
  16. 使用openpyxl的styles,实现写入值时加背景色
  17. 无法重启oracle数据库监听
  18. python模块之HTMLParser解析出URL链接
  19. GStreamer插件分类
  20. crontab定时执行

热门文章

  1. winserver 2008 找不到回收站的解决办法
  2. Windows10安装好Visual Studio2017后,找不到MFC向导
  3. vue 各种 import 引入
  4. connect failed: 127.0.0.1#953: connection refused
  5. 小部分安卓手机 reload 等方法不执行
  6. Spring定时器StopWatch
  7. CG-CTF CRYPTO部分wp
  8. python之命名元组的好处
  9. python之序列去重以及生成器、生成器函数、生成器表达式与迭代器浅谈
  10. bat批处理----copy和xcopy区别