hiho 1496 : 寻找最大值 高维前缀最大&次大

来源:互联网 发布:sql 替换字符 编辑:程序博客网 时间:2024/04/29 08:02

题目连接点这里

在qqq巨的教导下,,终于会一点点高维前缀了,,,

这题,,我们可以先枚举(a[i]&a[j])

然后,,我们就是需要求包含(a[i]&a[j])这个二进制位的最大和次大的数,这种数称为超集

在我的理解,,01高维前缀和,就是用来就 求一个集合的子集和,最小最大值,,或者一个集合的超集的和,最小最大值


#include<algorithm>#include<iostream>#include<cstring>#include<queue>#include<cmath>#include<cstdio>using namespace std;#define mem(x,y) memset(x,y,sizeof(x))#define FIN freopen("input.txt","r",stdin)#define fuck(x) cout<<x<<endlconst int k=20;#define INF 0x3f3f3f3f#define lson l,m,rt<<1typedef long long LL;#define rson m+1,r,rt<<1|1int cnt[1<<k];int pre[1<<k][2];int main(){    int T;    cin>>T;    while(T--)    {        mem(cnt,0);        mem(pre,0);        int n;        scanf("%d",&n);        for(int i=1; i<=n; i++)        {            int x;            scanf("%d",&x);            if(pre[x][0]==0) pre[x][0]=x;            else if(pre[x][1]==0) pre[x][1]=x;        }        for(int i=0; i<k; i++)            for(int j=(1<<k)-1; j>=0; j--)                if(~j&(1<<i))                {                    if(pre[j^(1<<i)][0]>pre[j][0])                    {                        pre[j][1]=pre[j][0];                        pre[j][0]=pre[j^(1<<i)][0];                    }                    if(pre[j^(1<<i)][1]>pre[j][1])                    {                        pre[j][1]=pre[j^(1<<i)][1];                    }                }        LL ans=0;        for(int i=0; i<=(1<<k)-1; i++)            ans=max(ans,i*((LL)pre[i][0]*pre[i][1]));        cout<<ans<<endl;    }    return 0;}


0 0
原创粉丝点击