CF888E Maximum Subsequence

Posted qyj060604

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF888E Maximum Subsequence相关的知识,希望对你有一定的参考价值。

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的主要内容,如果未能解决你的问题,请参考以下文章

CF 888E Maximum Subsequence

CF888E Maximum Subsequence-折半搜索

CF888E Maximum Subsequence (折半枚举+ two-pointers)

Codeforces 888E:Maximum Subsequence(枚举,二分)

CF888EMaximum Subsequence 折半搜索

[CF1082D]Maximum Diameter Graph