【题解】
引用ZYF神犇一句话:"显然位运算的极值问题都应该从高位向低位考虑。优先让这一位为0,如果行的话这一位就是0,否则就设为1。"
复杂度:O( logY * n^2 )
注意:第一次WA37是因为“1<<(LL)x-1LL”,这里第一个1没有写成1LL
【代码】
#include<stdio.h> #include<stdlib.h> #include<string.h> #define INF 100000 typedef long long LL; LL s[2005]; int f[105][105],g[2005]; LL ans=0,t; int n,A,B,len=0; int min(int a,int b) { if(a<b) return a; return b; } void work1() { int x,i,j; for(x=len;x>0;x--) { for(i=1;i<=n;i++) g[i]=INF;//g[0]=0; for(i=1;i<=n;i++) for(j=0;j<i;j++) if(g[j]<B) { t=s[i]-s[j]; if( (t>>(LL)x|ans)==ans && (t&1LL<<(LL)x-1LL)==0 ) g[i]=min(g[i],g[j]+1); } ans<<=1LL; if(g[n]>B) ans++; } } void work2() { int x,i,j,k; for(x=len;x>0;x--) { memset(f,0,sizeof(f)); f[0][0]=1; for(i=1;i<=n;i++) for(j=1;j<=i;j++) for(k=0;k<i;k++) if(f[k][j-1]) { t=s[i]-s[k]; if( (t>>(LL)x|ans)==ans && (t&1LL<<(LL)x-1LL)==0 ) f[i][j]=1; } for(i=A;i<=B;i++) if(f[n][i]) break; ans<<=1; if(i>B) ans++; } } int main() { int i; scanf("%d%d%d",&n,&A,&B); for(i=1;i<=n;i++) { scanf("%lld",&s[i]); s[i]+=s[i-1]; } for(t=s[n];t>0;t>>=1) len++; if(A==1) work1(); else work2(); printf("%lld",ans); return 0; }