Hihocoder 1496 尋找最大值(狀態壓縮 + 高位前綴和)
阿新 • • 發佈:2018-03-14
ems sca 題目 二進制 包含 aps void post 前綴
題目鏈接 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\n", ans); } return 0; }
Hihocoder 1496 尋找最大值(狀態壓縮 + 高位前綴和)