T105017 seq(DP)

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;
}