对于n<=40的情况,正常暴搜无疑要寄,那么我们可以分别从前一半和后一半开始搜,再对所搜的内容排序后,每一个在后面里二分出符合的答案。
和这题很像。
醉漾轻舟,信流引到花深处 (二分 折半搜索)_Jack_00_的博客-CSDN博客
/*keep on going and never give up*/
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define fast std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int maxn=2e6+10;
const int mod=1e9+7;
int n,m,ans,a[maxn];
vector<int>v1,v2;
void dfs(int l,int r,int sum,vector<int> &x){
if(sum>m)return ;
if(l>r){
x.push_back(sum);return ;
}
dfs(l+1,r,sum+a[l],x);dfs(l+1,r,sum,x);
}
signed main(){
fast
cin>>n>>m;
int mid=n>>1;
for(int i=1;i<=n;i++) cin>>a[i];
dfs(1,mid,0,v1);dfs(mid+1,n,0,v2);
sort(v1.begin(),v1.end());
int ans=0;
for(int i=0;i<v2.size();i++)
ans+=upper_bound(v1.begin(),v1.end(),m-v2[i])-v1.begin();
cout<<ans;
}