HihoCoder - 1496:寻找最大值(高维前缀和||手动求子集)

描述

给定N个数A1, A2, A3, ... AN,小Ho想从中找到两个数Ai和Aj(i ≠ j)使得乘积Ai × Aj × (Ai AND Aj)最大。其中AND是按位与操作。  

小Ho当然知道怎么做。现在他想把这个问题交给你。

输入

第一行一个数T,表示数据组数。(1 <= T <= 10)  

对于每一组数据:

第一行一个整数N(1<=N<=100,000)

第二行N个整数A1, A2, A3, ... AN (0 <= Ai <220)

输出

一个数表示答案

样例输入

2
3
1 2 3
4
1 2 4 5

样例输出

12
80

思路:Ai*Aj*(Ai&Aj)我们枚举第三部分,假设第三部分为x=Ai&Aj,然后我们取x的超集的最大值和次大值即可。

对于每个Ai我们可以枚举子集,用Ai取更新子集的最大次大值。4777ms;

#include<bits/stdc++.h>
using namespace std;
const int maxn=(1<<20)+10;
int Mx[maxn],Se[maxn]; long long ans;
int main()
{
    int T,N,x;
    scanf("%d",&T);
    while(T--){
        memset(Mx,0,sizeof(Mx));
        memset(Se,0,sizeof(Se));
        scanf("%d",&N);
        for(int i=1;i<=N;i++){
            scanf("%d",&x);
            for(int j=x;j;j=(j-1)&x){
                if(x>Mx[j]){
                    Se[j]=Mx[j]; Mx[j]=x;
                }
                else if(x>Se[j]) Se[j]=x;
            }
        }
        ans=0;
        for(int i=1;i<maxn;i++) ans=max(ans,(long long)i*Mx[i]*Se[i]);
        printf("%lld\n",ans);
    }
    return 0;
}

也可以利用高维前缀和来维护最大次大值。1586ms。

(目前见到的三种:高维前缀和维护了X集之和,位置的最小值,最大次大值。ORZ

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1<<20;
int Mx[maxn+10],Se[maxn+10]; ll ans;
int main()
{
    int T,N,x;
    scanf("%d",&T);
    while(T--){
        memset(Mx,0,sizeof(Mx));
        memset(Se,0,sizeof(Se));
        scanf("%d",&N);
        for(int i=1;i<=N;i++){
            scanf("%d",&x);
            if(x>Mx[x]) Mx[x]=x;
            else Se[x]=x;
        }
        for(int i=0;i<20;i++){
            for(int j=0;j<maxn;j++){
                if(!(j&(1<<i))){
                    if(Mx[j|(1<<i)]>=Mx[j]){
                        Se[j]=max(Mx[j],Se[j|(1<<i)]);
                        Mx[j]=Mx[j|(1<<i)];
                    }
                    else Se[j]=max(Mx[j|(1<<i)],Se[j]);
                }
            }
        }
        ans=0;
        for(int i=1;i<maxn;i++) ans=max(ans,(ll)i*Mx[i]*Se[i]);
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hua-dong/p/9950645.html