30分做法:
直接暴力选数即可:
#include<queue> #include<cstring> #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; typedef long long ll; const int maxm=1007; const int mo=1e9+7; int a[maxm]; int n,len1,len2; ll ans; bool flag[maxm]; int tmp[maxm],tmp1[maxm]; void dfs1(int x,int len) { if(x==len+1) { int sum; for(int i=1;i<=len1;i++) { if(i==1) sum=a[tmp[i]]; else sum^=a[tmp[i]]; } int sum1; for(int i=1;i<=len;i++) { if(i==1) sum1=a[tmp1[i]]; else sum1&=a[tmp1[i]]; } if(sum==sum1) { ans++; ans%=mo; } return; } for(int i=tmp1[x-1]+1;i<=n;i++) { if(flag[i]) continue; flag[i]=1; tmp1[x]=i; dfs1(x+1,len); flag[i]=0; } } void dfs(int x,int len) { if(x==len+1) { tmp1[0]=tmp[x-1]; len1=len; for(int i=1;i<=n-tmp[x-1]+1;i++) { dfs1(1,i); } return; } for(int i=tmp[x-1]+1;i<=n;i++) { if(flag[i]) continue; flag[i]=1; tmp[x]=i; dfs(x+1,len); flag[i]=0; } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",a+i); } for(int i=1;i<=n-1;i++)//枚举S选的个数 { dfs(1,i); } printf("%lld ",ans); return 0; }
满分做法:
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<set> #include<vector> #include<cmath> using namespace std; typedef long long ll; const ll mo = 1e9 + 7; ll dp1[1010][2021],dp2[1010][2020],ans; int a[1010]; int n; ll mul(ll a,ll b){ ll ans = 0,base = a; while(b != 0){ if(b & 1)ans = (ans + base) % mo; base = (base + base)% mo; b >>= 1; } return ans; } int main() { scanf("%d",&n); for(int i = 1;i <= n ;i ++){ scanf("%d",&a[i]); dp2[i][a[i]] = 1; dp1[i][a[i]] = 1; } for(int i = 2;i <= n ;i ++){ for(int j = 0;j <= 1025;j ++){ dp1[i][j^a[i]] = (dp1[i][j^a[i]]%mo + dp1[i-1][j]%mo)%mo; dp1[i][j] = (dp1[i][j]%mo + dp1[i-1][j]%mo)%mo; } } for(int i = n - 1;i >= 1; i --){ for(int j = 0;j <= 1025;j ++){ dp2[i][j&a[i]] = (dp2[i][j&a[i]]%mo + dp2[i+1][j]%mo)%mo; dp2[i][j] = (dp2[i][j]%mo + dp2[i+1][j]%mo)%mo; } } for(int i = 1;i <= n ;i ++){ for(int s = 0;s <= 1024;s ++){ ans = (ans + (dp1[i][s] - dp1[i-1][s] + mo)%mo*dp2[i + 1][s]%mo)%mo;//做差值为新产生的方案,防止重复 } } cout<<ans<<endl; return 0; }