50pts求条调

P4799 [CEOI2015 Day2] 世界冰球锦标赛

_FastFT2013 @ 2024-02-03 08:14:28

折半搜索+二分,无TLE,不知道哪里错了

#include<iostream>
#include<vector>
using namespace std;
const int N=45;
int n;
long long m;
long long a[N];
long long cnt=0;
long long b[1<<25],tot=0;
void dfs(int u,int sum){
    if(sum>m)return;
    if(u==n/2+1){
        b[++tot]=sum;
        return;
    }
    dfs(u+1,sum);
    dfs(u+1,sum+a[u]);
}
void merge(long long a[],int l,int m,int r){
    int len1=m-l+1,len2=r-m;
    long long left[len1],right[len2];
    for(int i=0;i<len1;i++)left[i]=a[l+i];
    for(int i=0;i<len2;i++)right[i]=a[m+i+1];
    int i=0,j=0;
    while(i<len1&&j<len2){
        if(left[i]<right[j]){
            a[l++]=left[i++];
        }else{
            a[l++]=right[j++];
        }
    }
    while(i<len1)a[l++]=left[i++];
    while(j<len2)a[l++]=right[j++];
}
void mergesort(long long a[],int l,int r){
    if(l>=r)return;
    int mid=(l+r)>>1;
    mergesort(a,l,mid);
    mergesort(a,mid+1,r);
    merge(a,l,mid,r);
}
bool check(int mid,long long sum){
    return sum+b[mid]<=m;
}
void dfs2(int u,long long sum){
    if(sum>m)return;
    if(u==n+1){
        int l=1,r=tot;
        while(l<r){
            int mid=(l+r+1)>>1;
            if(check(mid,sum))l=mid;
            else r=mid-1;
        }
        cnt+=l;
        return;
    }
    dfs2(u+1,sum);
    dfs2(u+1,sum+a[u]);
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    dfs(1,0);
    mergesort(b,1,tot);
    dfs2(n/2+1,0);
    cout<<cnt;
    return 0;
}

by _FastFT2013 @ 2024-02-03 14:35:06

不开long long见祖宗,此贴终


|