I love max and multiply(位运算处理)
题目:
Description
Input
The first line contains an integer T . Then T test cases follow.
Each test case contains three lines.
- The first one contains an integer nn(1≤n≤2^18) — length of the array aa.
- The second one contains nn integers A0,A1,A2,…,An−1,(|Ai|≤10^9)
- The third one contains nn integers B0,B1,B2,…,Bn−1(|Bi|≤10^9)
∑n≤2^19
Output
Samples
1 4 9 1 4 1 5 4 1 1
Output
54
题解:
i & j >= k 转化为 i & j >= i && i <= n - 1
并且我们从i = n - 1 开始往后扫,维护 i —> n-1 之内的最大值,然后算i贡献的时候要和c[i+1]取一个max
maxa[i]表示max(a[j])(a[j])(j &i > = i)
由于可能出现负数,所以还要处理最小值
预处理出maxa,maxb,mina,minb
代码:
#include<iostream> #include<algorithm> using namespace std; const int maxn=1e6+100; typedef long long ll; const int mod=998244353; ll a[maxn],maxa[maxn],mina[maxn]; ll b[maxn],maxb[maxn],minb[maxn]; ll c[maxn]; int main(){ int t; cin>>t; while(t--){ int n; cin>>n; for(int i=0;i<n;i++){ scanf("%lld",&a[i]); maxa[i]=mina[i]=a[i]; } for(int i=0;i<n;i++){ scanf("%lld",&b[i]); maxb[i]=minb[i]=b[i]; } for(int i=n-1;i>=0;i--){ for(int j=0;(1<<j)<n;j++){ if((i|(1<<j))>=n) continue; maxa[i]=max(maxa[i],maxa[i|(1<<j)]); maxb[i]=max(maxb[i],maxb[i|(1<<j)]); mina[i]=min(mina[i],mina[i|(1<<j)]); minb[i]=min(minb[i],minb[i|(1<<j)]); } } ll ans=0; c[n]=-1e18; for(int i=n-1;i>=0;i--){ c[i]=max({c[i+1],maxa[i]*maxb[i],maxa[i]*minb[i],mina[i]*minb[i],mina[i]*minb[i]}); ans=(ans+c[i])%mod; } cout<<(ans+mod)%mod<<endl; } }