Codeforces F. Bits And Pieces(位运算)

传送门.

位运算的比较基本的题。

考虑枚举\(i\),然后二进制位从大到小考虑, 对于第\(w\)位,如果\(a[i][w]=1\),那么对\(j、k\)并没有什么限制。

如果\(a[i][w]=0\),那么我们希望\((a[j]~and~a[k])[w]=1\),结合前面的限制,就是给定\(x\),问有没有\(x∈a[j]~and~a[k](i<j<k)\)

那么这应该是做一个高维后缀max和次max就能解决的事。

Code:


#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x; i <= y; i ++)
#define ff(i, x, y) for(int i = x; i <  y; i ++)
#define fd(i, x, y) for(int i = x; i >= y; i --)
#define pp printf
#define ll long long
using namespace std;
 
const int N = 1e6 + 10;
 
int n, a[N];
    
const int M = 1 << 21;
 
int f[M], g[M];
 
void add(int x, int i) {
    if(x > f[i]) {
        g[i] = f[i];
        f[i] = x;
    } else 
    if(x > g[i]){
        g[i] = x;
    }
}
 
const int inf = 1e9;
 
int main() {
    scanf("%d", &n);
    fo(i, 1, n) {
        scanf("%d", &a[i]);
        add(i, a[i]);
    }
    fo(i, 0, 20) {
        ff(j, 0, 1 << 21) {
            if(!(j >> i & 1))   {
                add(f[j + (1 << i)], j);
                add(g[j + (1 << i)], j);
            }
        }
    }
    ff(j, 0, 1 << 21) {
        if(f[j] != g[j]) {
            f[j] = g[j];
        } else {
            f[j] = 0;
        }
    }
    int ans = 0;
    fo(i, 1, n - 2) {
        int x = 0;
        fd(j, 20, 0) {
            if(!(a[i] >> j & 1)) {
                x += 1 << j;
                if(g[x] <= i) {
                    x -= 1 << j;
                }
            }
        }
        ans = max(ans, x | a[i]);
    }
    pp("%d", ans);
}

转载于:https://www.cnblogs.com/coldchair/p/11509154.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值