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(1n2^18) — length of the array aa.
  • The second one contains nn integers A0,A1,A2,,An1,(|Ai|10^9)
  • The third one contains nn integers B0,B1,B2,,Bn1(|Bi|10^9)

n2^19

Output

Samples

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

 

posted @ 2021-07-25 19:30  lipu123  阅读(99)  评论(0)    收藏  举报