话说莫非所有位运算都可以用贪心解决么……太珂怕啦……
一直把或运算看成异或算我傻逼……
考虑从高位到低位贪心,如果能使答案第$i$位为0那么肯定比不为$0$更优
然后考虑第$i$位是否能为$0$
设$f[i][j]$表示将前$i$个数分为$j$段,能否在最高位到第$i+1$位都与当前$ans$一致的情况下使第$i$位为0,可以的话$f[i][j]$为1,否则为0
考虑状态如何转移
如果$f[k][j-1]$为1且$sum[i]-sum[k]$的第$i$位为0则可以由$f[k][j-1]$转移到$f[i][j]$(其中$sum$表示前缀和)
考虑如何判断,如果$f[k][j-1]==1$且
(下面的$k$和上面那个$k$无关,因为变量有点多重复去了……)
$((sum[i]-sum[k])>>k|ans)== ans$(最高位到倒数第k+1位是否与ans一致)
$((S[i]-S[k])&1<<(k-1))==0$(倒数第k位能否为0)
那么就可以转移了
对于每个$x$,若$f[n][A~B]$有至少一个为1,$ans$的第$k$位就可以为0
然后因为时间复杂度过不了最后一个子任务……所以$A=1$的时候特判一下……
具体来说就是因为段数只有上限,所以把$f$数组的第二维省掉,就能降一个n
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #define ll long long 6 #define inf 0x3f3f3f3f 7 using namespace std; 8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 9 char buf[1<<21],*p1=buf,*p2=buf; 10 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;} 11 inline int read(){ 12 #define num ch-'0' 13 char ch;bool flag=0;int res; 14 while(!isdigit(ch=getc())) 15 (ch=='-')&&(flag=true); 16 for(res=num;isdigit(ch=getc());res=res*10+num); 17 (flag)&&(res=-res); 18 #undef num 19 return res; 20 } 21 const int N=2005; 22 ll sum[N];int f[105][105],g[N]; 23 ll ans=0,t;int n,l,r,len=0; 24 void solve1(){ 25 int x,i,j; 26 for(x=len;x;--x){ 27 for(i=1;i<=n;++i) g[i]=inf; 28 for(i=1;i<=n;++i) 29 for(j=0;j<i;++j) 30 if(g[j]<r){ 31 t=sum[i]-sum[j]; 32 if((t>>(ll)x|ans)==ans&&(t&1ll<<(ll)x-1ll)==0) cmin(g[i],g[j]+1); 33 } 34 ans<<=1ll; 35 if(g[n]>r) ++ans; 36 } 37 } 38 void solve2(){ 39 int x,i,j,k; 40 for(x=len;x;--x){ 41 memset(f,0,sizeof(f)); 42 f[0][0]=1; 43 for(i=1;i<=n;++i) 44 for(j=1;j<=i;++j) 45 for(k=0;k<i;++k) 46 if(f[k][j-1]){ 47 t=sum[i]-sum[k]; 48 if((t>>(ll)x|ans)==ans&&(t&1ll<<(ll)x-1ll)==0) f[i][j]=1; 49 } 50 for(i=l;i<=r;++i) 51 if(f[n][i]) break; 52 ans<<=1ll; 53 if(i>r) ++ans; 54 } 55 } 56 int main(){ 57 // freopen("testdata.in","r",stdin); 58 n=read(),l=read(),r=read(); 59 for(int i=1;i<=n;++i) 60 sum[i]=sum[i-1]+read(); 61 for(t=sum[n];t;t>>=1) ++len; 62 l==1?solve1():solve2(); 63 printf("%lld ",ans); 64 return 0; 65 }