码迷,mamicode.com
首页 > 其他好文 > 详细

CF888E Maximum Subsequence

时间:2019-09-15 16:48:18      阅读:85      评论:0      收藏:0      [点我收藏+]

标签:turn   搜索   style   ace   while   sequence   c++   const   ons   

CF888E Maximum Subsequence

有一种叫做折半搜索的好东西

我们把数列劈成两半,分别搜索,再合并

合并可以排序+二分或者排序+单调性

代码极短

#include<bits/stdc++.h>
using namespace std;
const int N=37;
const int M=5000005;
typedef long long ll;
int n;
ll m;
ll a[N];
int mi;
ll s1[M],s2[M];
int cnt1=0,cnt2=0;
ll ans=0;
ll llmax(ll x,ll y){
    return x>y?x:y;
}
inline void dfs(int x,ll val,int t,int o){
    if(x==t){
        if(o==1) s1[++cnt1]=val;
        else s2[++cnt2]=val;
        return;
    }
    dfs(x+1,val,t,o);
    dfs(x+1,(val+a[x+1])%m,t,o);
}
inline int serch(int x){
    int l=1,r=cnt2,ans=0;
    s2[0]=0;
    while(l<=r){
        int mid=(l+r)>>1;
        if(s2[mid]<x) ans=mid,l=mid+1;
        r=mid-1;
    }
    return s2[ans];
}
inline bool cmp(ll x,ll y){
    return x<y;
}
int main(){
    scanf("%d%d",&n,&m);
    mi=n/2;
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]),a[i]%=m;
    dfs(0,0,mi,1);
    dfs(mi,0,n,2); 
    for(int i=1;i<=cnt1;i++) ans=llmax(ans,s1[i]);
    for(int i=1;i<=cnt2;i++) ans=llmax(ans,s2[i]);
    sort(s1+1,s1+cnt1+1,cmp);
    sort(s2+1,s2+cnt2+1,cmp);
    int j=cnt2;
    s2[0]=0;
    for(int i=1;i<=cnt1;i++){
        ans=llmax(ans,(s1[i]+s2[cnt2])%m);
        while(j>0&&s2[j]>=m-s1[i]) j--;
        ans=llmax(ans,(s1[i]+s2[j])%m);
    }
    printf("%lld\n",ans);
    return 0;
} 

 

CF888E Maximum Subsequence

标签:turn   搜索   style   ace   while   sequence   c++   const   ons   

原文地址:https://www.cnblogs.com/QYJ060604/p/11523275.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!