如果,那么(具有传递性)
设表示二进制数的集合,且满足。
如果我们从大到小计算,那么。因为,所以此时集合已经得到了,并且可以保证的是所有满足的下标在上述的某个集合中。
比如:n=32
...
设表示,表示,表示,表示。那么我们可以在求出的同时算出这些数组。
假设表示,如果下标从大到小计算,那么。
code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = (2<<18)+7,mod=998244353; const ll inf=1e18; ll A[maxn],a[maxn],B[maxn],b[maxn]; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int T,n; cin>>T; while(T--) { cin>>n; for(int i=0;i<n;++i) cin>>a[i],A[i]=a[i]; for(int i=0;i<n;++i) cin>>b[i],B[i]=b[i]; int m=1; while(m<n) m<<=1; for(int i=n;i<m;++i) A[i]=B[i]=-inf,a[i]=b[i]=inf; for(int j=1;j<m;j<<=1) for(int i=m-1;~i;--i) if(!(i&j)){ A[i]=max(A[i],A[i^j]); B[i]=max(B[i],B[i^j]); a[i]=min(a[i],a[i^j]); b[i]=min(b[i],b[i^j]); } ll ans(0),last=-inf,tmp; for(int i=n-1;~i;--i) { tmp=-inf; if(A[i]!=-inf&&B[i]!=-inf) tmp=max(tmp,A[i]*B[i]); if(A[i]!=-inf&&b[i]!=-inf) tmp=max(tmp,A[i]*b[i]); if(a[i]!=-inf&&B[i]!=-inf) tmp=max(tmp,a[i]*B[i]); if(a[i]!=-inf&&b[i]!=-inf) tmp=max(tmp,a[i]*b[i]); last=max(tmp,last); ans=(ans+last)%mod; } cout<<(ans+mod)%mod<<'\n'; } return 0; }