C. Creative Snap(dfs+剪枝)

https://codeforces.com/problemset/problem/1111/C


思路:

直接暴搜是2^30肯定不行呀..

但是看这个k只有1e5,均分构造也跑不到太大。

所以log找一段区间里的人是否为0,为0就可以直接return了

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL a[maxn];
LL n,k,A,B;
LL dfs(LL l,LL r){

    LL num=upper_bound(a+1,a+1+k,r)-lower_bound(a+1,a+1+k,l);
    if(num==0) return A;

    LL ans=B*(r-l+1)*num;///直接全删
    if(l==r) return ans;

    LL mid=(l+r)>>1;

    ans=min(ans,dfs(l,mid)+dfs(mid+1,r));///再拆

    return ans;
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  cin>>n>>k>>A>>B;
  for(LL i=1;i<=k;i++){
      LL x;cin>>x;
      a[i]=x;
  }
  sort(a+1,a+1+k);
  LL ans=dfs(1,(1<<n));
  cout<<ans<<"\n";
return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/114681063