CodeForces

CodeForces - 981D
从高位到低位去枚举,如果存在一种分配>=(ans|i),ans|=i;
检验的时候用区间dp,f[i][j]表示前i个分成j段能不能成功,当然每一段都>=(ans|i)

#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cstring>
#define inf 2147483647
#define N 1000010
#define p(a) putchar(a)
#define For(i,a,b) for(long long i=a;i<=b;++i)
//by war
//2020.2.22
using namespace std;
long long n,k,ans;
long long a[N],f[100][100];
void in(long long &x){
    long long y=1;char c=getchar();x=0;
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    x*=y;
}
void o(long long x){
    if(x<0){p('-');x=-x;}
    if(x>9)o(x/10);
    p(x%10+'0');
}

bool check(long long x){
    memset(f,0,sizeof(f));
    f[0][0]=1;
    For(j,1,k)
        For(i,1,n)
            For(k,1,i)
                if(((a[i]-a[k-1])&x)==x&&f[k-1][j-1]) f[i][j]=1;
    return f[n][k];
}

signed main(){
    in(n);in(k);
    For(i,1,n){
        in(a[i]);
        a[i]+=a[i-1];
    }
    for(long long i=(long long)1<<60;i;i>>=1){
        if(check(ans|i)) ans|=i;
    }
    o(ans);
    return 0;
}
原文地址:https://www.cnblogs.com/war1111/p/12346944.html