如果,那么
(具有传递性)
设表示二进制数
的集合,且满足
。
如果我们从大到小计算,那么
。因为
,所以此时集合
已经得到了,并且可以保证的是所有满足
的下标
在上述的某个集合
中。
比如: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;
} 
京公网安备 11010502036488号