zoukankan      html  css  js  c++  java
  • Hihocoder 1496 寻找最大值(状态压缩 + 高位前缀和)

    题目链接  Hiho 1496

    设$f[i]$为二进制集合包含$i$的最大的两个数,这个东西用高维前缀和维护。

    高位前缀和转移的具体方案 :枚举每一位,然后枚举每个集合,大的转移到小的。

    注意合并的时候最好别用$std::sort$(我一开始被卡常数了)

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define fi		first
    #define se		second
    
    typedef long long LL;
    typedef pair <int, int> PII;
    
    int T;
    int n;
    int c[6];
    PII f[(1 << 20) + 10];
    LL  ans;
    
    
    inline void up(PII &a, PII b){
    	if (b.fi > a.fi){
    		a.se = a.fi;
    		a.fi = b.fi;
    	}
    
    	else if (b.fi > a.se){
    		a.se = b.fi;
    	}
    
    	if (b.se > a.fi){
    		a.se = a.fi;
    		a.fi = a.se;
    	}
    
    	else if (b.se > a.se){
    		a.se = b.se;
    	}
    }
    
    int main(){
    
    	scanf("%d", &T);
    	while (T--){
    		scanf("%d", &n);
    		memset(f, -1, sizeof f);
    
    		rep(i, 1, n){
    			int x;
    			scanf("%d", &x);
    			if (~f[x].fi) f[x].se = x;
    			else f[x].fi = x;
    		}
    
    		rep(i, 0, 19){
    			rep(j, 0, (1 << 20) - 1){
    				if ((1 << i) & j){
    					up(f[j ^ (1 << i)], f[j]);
    				}
    			}
    		}
    
    		ans = 0;
    		rep(i, 0, (1 << 20) - 1) if ((~f[i].fi) && (~f[i].se)) ans = max(ans, 1ll * i * f[i].fi * f[i].se);
    		printf("%lld
    ", ans);
    	}
    
    	return 0;
    }
    

      

  • 相关阅读:
    [NOI2002]银河英雄传说
    Splay普及版
    线段树普及版
    长连接与短连接
    【HTTP】中Get/Post请求区别
    【HTML】知识笔记
    SVN使用教程总结
    《人生只有一次,去做自己喜欢的事》读书笔记
    【HTTP】无状态无连接的含义
    【HTML】解析原理
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/8563520.html
Copyright © 2011-2022 走看看