C - Anu Has a Function(div2)

骗过我的水题

题意: 定义函数 f ( a , b ) = a ∣ b − b f(a, b) = a|b - b f(a,b)=abb, 现有数组 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),an1),an) 现在要求你求整个式子的最大值, 并输出值最大时的a的顺序

Face

数据范围: 1 ≤ n ≤ 1 e 5 , ∣ a i ∣ ≤ 1 e 9 1\leq n\leq1e5, |a_i| \leq 1e9 1n1e5,ai1e9

Tutorial: 列个表出来:

abval
000
010
101
110

你有没有发现什么?

再看这张表:

a~bval
010
000
111
100

也许你会spot : f ( a , b ) = a ∣ b − b = a & ( f(a, b) = a|b - b = a\&( f(a,b)=abb=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] << " ";
        }
    }



}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值