ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1208F Bits And Pieces

2022-08-13 09:01:56  阅读:172  来源: 互联网

标签: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
来源: https://www.cnblogs.com/zuytong/p/16581977.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有