朴素的暴力是 Cknk!k2 ,但事实上很多组合根本不可能达到ans,所以枚举了一个组合后先忽略一定是连续的异或和的限制, 2k 判答案是否有可能超过ans,有可能再 k!k2 找,在随机数据下表现良好QAQ
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
const int maxn = 21;
int To[1<<21];
int n,k,L,ans,al;
int a[maxn];
int t[maxn],tp;
int v[210],ti;
struct node{int i[maxn];}P[1100]; int pn;
bool use[maxn];
void build()
{
if(tp==k)
{
++pn; for(int i=1;i<=tp;i++) P[pn].i[i]=t[i];
return;
}
for(int i=1;i<=k;i++) if(!use[i])
{
t[++tp]=i; use[i]=true;
build();
use[i]=false; tp--;
}
}
void judge()
{
++ti;
for(int i=1;i<al;i++)
{
int l,now=0;
for(int j=i;j;j=j-l)
{
l=lowbit(j);
now^=t[To[l]+1];
}
v[now]=ti;
}
for(int i=L;i<=ans+1;i++) if(v[i]!=ti) return;
int als=0; for(int i=1;i<=tp;i++) als^=t[i];
for(int ii=1;ii<=pn;ii++)
{
++ti;
for(int i=1;i<=k;i++)
{
int now=0;
for(int j=i;j<=k;j++)
{
now^=t[P[ii].i[j]];
v[now]=ti;
v[als^now]=ti;
}
}
for(int i=L;;i++) if(v[i]!=ti)
{
ans=max(ans,i-1);
break;
}
}
}
void dfs(const int nowi)
{
if(tp==k) { judge(); return; }
if(nowi>n) return;
for(int i=nowi;i<=n&&n-i+1+tp>=k;i++)
{
t[++tp]=a[i]; dfs(i+1); tp--;
}
}
int main()
{
for(int i=0;i<=20;i++) To[1<<i]=i;
while(scanf("%d%d%d",&n,&k,&L)!=EOF)
{
memset(v,0,sizeof v); ti=0;
ans=L-1; al=1<<k;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
pn=0;tp=0; build();
tp=0; dfs(1);
if(ans==L-1) puts("0");
else printf("%d\n",ans);
}
return 0;
}