分析

有了位运算
想到的一定是贪心
因为答案从高位到低位贪心一定是最优的
那么我们可以考虑判断当前答案是否可行
f[][]表示当前到了i个位置,分为了j组是否成立
转移时枚举前一个位置,判断这一组是否为当前所需答案的超集即可
时间复杂度:

温馨提示:本题数据范围似乎有问题,需要达到左移60位才可过(只移50位不可过)

代码

//CF981D
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

#define ll long long
#define cl(x, y) memset((x), (y), sizeof(x))
#define rep(i, a, b) for(ll i = a; i <= b; i++)
#define per(i, a, b) for(ll i = a; i >= b; i--)
#define de(x) cerr << #x << " = " << x << " "
#define inc_mod(x, y) x = ((x - y) % mod + mod) % mod
#define add_mod(x, y) x = (x + y) % mod
#define mul_mod(x, y) x = (x * y) % mod
#define lowbit(x) (x & (-x))
#define inf 0x3f3f3f3f3f3f3f3f
#define mod 998244353
#define rson (x << 1 | 1)
#define lson (x << 1)
using namespace std;
const ll maxn = 55;

bool f[maxn][maxn];
ll ans, total, limit;
ll num[maxn], pre[maxn];

inline void file() {
    freopen(".in", "r", stdin);
    freopen(".out", "w", stdout);
}
signed main() {
    // file();
    ios::sync_with_stdio(false);
    cin >> total >> limit;
    rep(i, 1, total) cin >> num[i], pre[i] = pre[i - 1] + num[i];
    per(state, 60ll, 0ll) {
        cl(f, false);
        ll temp = ((1ll << state) | ans);
        f[0][0] = true; 
        rep(i, 1ll, total) rep(k, 1ll, min(limit, i))
            rep(j, 0ll, i - 1) {
                ll res = pre[i] - pre[j];
                if((res & temp) == temp) f[i][k] |= f[j][k - 1];
            }
        if(f[total][limit]) ans |= (1ll << state);
    }
    cout << ans << endl;
    // fclose(stdin);
    // fclose(stdout);
    system("pause");
    return 0;
}