显然我们发现如果连续两次进行异或操作的抵消的,所以可以插入一对或多对二次异或操作,然后剪枝dfs就可以了。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<cmath>
#include<algorithm>
#define inf 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const int mx=40;
int u,n,r;
int a[mx],b[mx],k[mx],p[mx],a1[mx];
ll ans;
void dfs(int step,int a[],int way){
int a1[mx];
if((u-step)%2==0){
ll cnt=0;
for(int i=1;i<=n;i++)
cnt+=a[i]*k[i];
ans=max(cnt,ans);
if(u==step) return ;
}
if(way){
for(int i=1;i<=n;i++) a1[i]=b[i]^a[i];
dfs(step+1,a1,0);
}
for(int i=1;i<=n;i++) a1[i]=a[p[i]]+r;
dfs(step+1,a1,1);
}
int main(){
while(cin>>n>>u>>r){
for(int i=1;i<=n;i++) scanf("%d",a+i);
for(int i=1;i<=n;i++) scanf("%d",b+i);
for(int i=1;i<=n;i++) scanf("%d",k+i);
for(int i=1;i<=n;i++) scanf("%d",p+i);
ans=-100000000001;
dfs(0,a,1);
printf("%lld\n",ans);
}
return 0;
}