Question:
There are n numbers. Two sets s and the set T are selected from the N number to ensure that all the elements in the original series are in
The left side of the element in set T. In addition, it is required that the values of the elements in set S and those of the elements in set t be used and computed
Values are equal. Ask how many such sets S and T can be selected.
Algorithm:
Left and right DP.
Use DP [I] [J] to represent the number of methods used to perform the previous I operation or calculate the number of J methods. The last value is not necessarily obtained.
This is a problem with the backpack. The same is true for the right side.
Repeated enumeration may occur. The enumerated I and I + 1 may be repeated. So we need to enumerate an intermediate value.
This median value belongs to the s set. It is not supported due to reverse operations.
Therefore, the DP equation should be changed to the number of the first I must contain the number of methods that do the nth I or obtain the value J, that is, the number of S [I] [J].
S [I] [J] = DP [I-1] [J ^ A [I].
The right side is also an operation, but pay attention to the subscript.
Then the long operation should be performed before multiplication. Otherwise, the multiplication operation may overflow and the long operation will be meaningless.
#include<cstdio>#include<iostream>#include<cstring>using namespace std;const int mod = 1000000000+7;typedef long long ll;int a[1010];int dp[1010][1025],dp1[1010][1025],s[1010][1025];int main(){ int T,n; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); memset(dp,0,sizeof(dp)); dp[0][0] = 1; for(int i=1;i<=n;i++) { for(int j=0;j<1024;j++) { dp[i][j] = dp[i-1][j]+dp[i-1][j^a[i]]; if(dp[i][j]>=mod) dp[i][j] -= mod; } for(int j=0;j<1024;j++) s[i][j] = dp[i-1][j^a[i]]; } memset(dp1,0,sizeof(dp1)); for(int i=n;i>=1;i--) { dp1[i][a[i]]++; for(int j=0;j<1024;j++) { dp1[i][j&a[i]] = (dp1[i][j&a[i]]+dp1[i+1][j])%mod; dp1[i][j] = (dp1[i][j]+dp1[i+1][j])%mod; } } int cnt = 0; for(int k=1;k<=n-1;k++) { for(int j=0;j<1024;j++) { cnt = (cnt+(ll)s[k][j]*dp1[k+1][j])%mod; if(cnt>=mod) cnt-=mod; } } printf("%d\n",cnt); } return 0;}