首页 > 其他分享 >CF1208F Bits And Pieces

CF1208F Bits And Pieces

时间:2022-08-13 09:01:33浏览次数:88  
标签:CF1208F int Mn sign Pieces 答案 include Bits define

传送门


思路

面对位运算,而且要求答案最大,我们应该想到一个贪心:从二进制最高位开始取,这样能保证答案最优

对于一个答案 \(x\) ,它可行当且仅当存在 \(i<j<k\),满足有 \(x\oplus w \subseteq a[i]\) 和 \(w\subseteq a[j],a[k]\)(这里 \(w\subseteq x\))

我们考虑记录 \(Mn[w]\) 为 \(w\subseteq a[i]\) 时 \(i\) 的最小值,\(Mx[w]\) 为 \(w\subseteq a[i]\) 时 \(i\) 的最大值(需要同时记录两个,因此要用二元组记录最大和次大)

显然可以用高维前缀和来完成

验证答案 \(x\) 是否可行时,我们只需要判断是否有 \(Mn[x\oplus w]<Mx[w]\)(\(w\subseteq x\))即可


代码

#include<iostream>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#define LL long long
#define FOR(i, x, y) for(int i = (x); i <= (y); i++)
#define ROF(i, x, y) for(int i = (x); i >= (y); i--)
#define PFOR(i, x) for(int i = he[x]; i; i = r[i].nxt)
inline int reads()
{
    int sign = 1, re = 0; char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') sign = -1; c = getchar();}
    while('0' <= c && c <= '9'){re = re * 10 + (c - '0'); c = getchar();}
    return sign * re;
}
#define pii std::pair<int, int>
#define mp std::make_pair
int n, a[1000005], Mn[(1 << 21)], ans;
pii Mx[(1 << 21)];
inline pii ud(pii a, pii b)
{
    int s[4]; s[0] = a.first, s[1] = a.second, s[2] = b.first, s[3] = b.second;
    std::sort(s, s + 4); return mp(s[3], s[2]);
}
inline bool chk(int x)
{
    for(int i = x; i; i = (i - 1) & x) if(Mn[x ^ i] < Mx[i].second) return 1;
    return (Mn[x] < Mx[0].second);
}
signed main()
{
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    n = reads();
    memset(Mn, 63, sizeof(Mn));
    FOR(i, 1, n) a[i] = reads(), Mn[a[i]] = std::min(Mn[a[i]], i);
    FOR(i, 1, n) Mx[a[i]] = ud(Mx[a[i]], mp(i, 0));
    FOR(i, 0, 20) ROF(j, (1 << 21) - 1, 0)
        if(!(j & (1 << i)))
            Mn[j] = std::min(Mn[j], Mn[j ^ (1 << i)]),
            Mx[j] = ud(Mx[j], Mx[j ^ (1 << i)]);
    ROF(i, 20, 0)
        if(chk(ans | (1 << i))) ans |= (1 << i);
    printf("%d", ans);
    return 0;
}

标签:CF1208F,int,Mn,sign,Pieces,答案,include,Bits,define
From: https://www.cnblogs.com/zuytong/p/16581977.html

相关文章