骗过我的水题
题意: 定义函数 f ( a , b ) = a ∣ b − b f(a, b) = a|b - b f(a,b)=a∣b−b, 现有数组 a a a表示 f ( f ( ⋯ f ( f ( a 1 , a 2 ) , a 3 ) , ⋯ a n − 1 ) , a n ) f(f(\cdots f(f(a_1, a_2), a_3), \cdots a_{n-1}), a_n) f(f(⋯f(f(a1,a2),a3),⋯an−1),an) 现在要求你求整个式子的最大值, 并输出值最大时的a的顺序
数据范围: 1 ≤ n ≤ 1 e 5 , ∣ a i ∣ ≤ 1 e 9 1\leq n\leq1e5, |a_i| \leq 1e9 1≤n≤1e5,∣ai∣≤1e9
Tutorial: 列个表出来:
a | b | val |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 1 |
1 | 1 | 0 |
你有没有发现什么?
再看这张表:
a | ~b | val |
---|---|---|
0 | 1 | 0 |
0 | 0 | 0 |
1 | 1 | 1 |
1 | 0 | 0 |
也许你会spot : f ( a , b ) = a ∣ b − b = a & ( f(a, b) = a|b - b = a\&( f(a,b)=a∣b−b=a&(~ b ) b) b)
于是整个式子就变成了
a
1
&
(
a_1\&(
a1&(~
a
2
)
&
(
a_2 )\&(
a2)&(~
a
3
)
…
a_3)\ldots
a3)…
求这个式子最大值显然就只与第一个元素有关了, 于是可以用前后缀和维护
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;
#define _rep(n, a, b) for (ll n = (a); n <= (b); ++n)
#define _rev(n, a, b) for (ll n = (a); n >= (b); --n)
#define _for(n, a, b) for (ll n = (a); n < (b); ++n)
#define _rof(n, a, b) for (ll n = (a); n > (b); --n)
#define oo 0x3f3f3f3f3f3f
#define ll long long
#define db double
#define eps 1e-8
#define bin(x) cout << bitset<10>(x) << endl;
#define what_is(x) cerr << #x << " is " << x << endl
#define met(a, b) memset(a, b, sizeof(a))
#define all(x) x.begin(), x.end()
#define pii pair<ll, ll>
#define pdd pair<db, db>
const ll mod = 1e9 + 7;
const ll maxn = 1e5 + 10;
#define lowbit(x) x &(-x)
ll pre[maxn], suf[maxn];
vector<ll> a;
ll n;
ll ask(int i) {
if (i == 1)return a[1] & suf[2];
if (i == n)return pre[n - 1] & a[i];
return pre[i - 1] & a[i] & suf[i + 1];
}
signed main()
{
cin >> n;
a.resize(n + 1);
ll fir_id = 1;
_rep(i, 1, n) {
cin >> a[i];
if (i == 1)pre[0] = ~a[i];
if (i == n) suf[n + 1] = ~a[i];
pre[i] = pre[i - 1] & (~a[i]);
}
_rev(i, n, 1) {
suf[i] = suf[i + 1] & (~a[i]);
}
_rep(i, 2, n) {
if(ask(fir_id) < ask(i)) {
fir_id = i;
}
}
cout << a[fir_id] << " ";
_rep(i, 1, n) {
if (i != fir_id) {
cout << a[i] << " ";
}
}
}