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; }
原文地址:https://www.cnblogs.com/QYJ060604/p/11523275.html
时间: 2024-10-08 18:44:51