Educational Codeforces Round 32 Maximum Subsequence CodeForces - 888E (meet-in-the-middle,二分,枚举)

You are given an array a consisting of n integers, and additionally an integer m. You have to choose some sequence of indices b1, b2, ..., bk (1 ≤ b1 < b2 < ... < bk ≤ n) in such a way that the value of is maximized. Chosen sequence can be empty.

Print the maximum possible value of .

Input
The first line contains two integers n and m (1 ≤ n ≤ 35, 1 ≤ m ≤ 109).

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109).

Output
Print the maximum possible value of .

Examples
Input
4 4
5 2 4 1
Output
3
Input
3 20
199 41 299
Output
19
Note
In the first example you can choose a sequence b = {1, 2}, so the sum is equal to 7 (and that's 3 after taking it modulo 4).

In the second example you can choose a sequence b = {3}.

Meaning of the questions:
to give you an array a, and a number m, allows you to select a subset of an array, so that the subset sum of the number and the maximum value of the modulo m.
Idea:
Meet at The-Middle-in-the ideas, the array is divided into two parts, each part of a number of the largest is the size of 35/2, for each section, we enumerate all the binary state, the first part of all child and obtaining the sum (modulo agree), then the second portion of the same operation, the modulo sum the array were added to v1 and v2, and finally to each number x of the first portion, a second portion to set find a number y, so that (x + y)% m as large as possible.
Then x + y is divided into two cases,
when x + y greater than or equal m,
then the result is x + ym, then y where we wish to select the maximum, so that the value may be larger.
Conversely is x + y <m
Y mx If less than the maximum, so that x + y is closer to m-1

See details Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
inline void getInt(int* p);
const int maxn=1000010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
ll a[60];
std::vector<ll> v1;
std::vector<ll> v2;
ll haf;
ll n,m;
void dfs1(int id,ll num)
{
    v1.pb(num%m);
    if(id<=haf)
    {
        dfs1(id+1,num);
        dfs1(id+1,num+a[id]);
    }
}
void dfs2(int id,ll num)
{
    v2.pb(num%m);
    if(id<=n)
    {
        dfs2(id+1,num);
        dfs2(id+1,num+a[id]);
    }
}
int main()
{
    // freopen("D:\\code\\text\\input.txt","r",stdin);
    //freopen("D:\\code\\text\\output.txt","w",stdout);
    gbtb;
    cin>>n>>m;
    repd(i,1,n)
    {
        cin>>a[i];
        a[i]%=m;
    }
    haf=(n>>1);
    dfs1(1,0ll);
    dfs2(haf+1,0ll);
    sort(ALL(v1));
    sort(ALL(v2));
    v1.erase(unique(ALL(v1)),v1.end());
    v2.erase(unique(ALL(v2)),v2.end());
    ll ans=0ll;
    int p=sz(v2);
    int q=sz(v1);
    for(auto x:v1)
    {
        int pos=lower_bound(ALL(v2),m-x)-v2.begin();
        if(pos>=1&&pos<p)
        {
            ans=max(ans,(x+v2[pos-1])%m);
        }
        ans=max(ans,(x+v2[p-1])%m);
    }
    cout<<ans<<endl;
    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    }
    else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}

Guess you like

Origin www.cnblogs.com/qieqiemin/p/11098151.html