显然我们发现如果连续两次进行异或操作的抵消的,所以可以插入一对或多对二次异或操作,然后剪枝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; }