抽象化题意:

一共有 \(m\) 个元素,给定 \(n\) 个集合,每个集合的元素不超过 \(15\) 个,求出一个元素个数最多的集合 \(S\) 是至少 \(\lceil \dfrac{n}{2} \rceil\) 个集合的子集。

其中$ p $ $ (1 \le n \le 2 \cdot 10^5, 1 \le p \le m \le 60) $

我们先假设 \(limit= \lceil \dfrac{n}{2} \rceil\)

先考虑最基础的暴力,如果我们每次枚举答案集合 \(S\) ,然后再计算出是否有大于等于 \(limit\) 个集合是 \(S\) 的超集,更新答案

计算超集可以通过 \(SOSDP\) ,仍然TLE,先从题目本质入手,它是让我们求一个集合使得是至少 \(\lceil \dfrac{n}{2} \rceil\) 个集合的子集,那么这个答案显然是某 \(\lceil \dfrac{n}{2} \rceil\) 个集合的子集,那如果我们随机任取一个集合,正确答案是它子集的概率就是50%,那我们直接随 \(num\) 次,可以直接让答案错误的概率降到极低,错误的概率就是 \(\dfrac{1}{2^{num}}\) 。

也就是说随机50次的样子,每次对于随机到的集合,通过 \(O(p\times2^p)\) 来计算超集,具体细节就是需要搞个vector来存某位是1的位置就行了。

代码:

#include<bits/stdc++.h>

#define int long long 

using namespace std;

template<class T>

inline T read(){
T r=0,f=0;
char c;
while(!isdigit(c=getchar()))f|=(c=='-');
while(isdigit(c))r=(r*10)+(c^48),c=getchar();
return f?-r:r;
} int n,m,p,limit; int a[200005]; bool flag[200005]; vector<int>g; inline int idx(char c){
return c-'0';
} int dp[1000005]; int ans; mt19937 rd(time(0)); inline void work(){
int pos;
while(1){
pos=rd()%n+1;
if(!flag[pos]){flag[pos]=true;break;}
}
g.clear();
int num=a[pos];
for(int i=0;i<m;i++){
if((num>>i)&1)g.emplace_back(i);
}
memset(dp,0,sizeof(dp));
int S=g.size();
for(int i=1;i<=n;i++){
int tmp=0;
for(int j=0;j<S;j++){
if((a[i]>>g[j])&1)tmp|=(1<<j);
}
++dp[tmp];
}
for(int i=0;i<S;i++){
for(int j=0;j<(1ll<<S);j++){
if(!((j>>i)&1))dp[j]+=dp[j^(1<<i)];
}
}
int res=0;
for(int i=1;i<(1ll<<S);i++){
if(dp[i]>=limit){
if(__builtin_popcountll(res)<__builtin_popcountll(i))res=i;
}
}
int res2=0;
for(int i=0;i<S;i++){
if((res>>i)&1)res2|=(1ll<<g[i]);
}
if(__builtin_popcountll(res)>__builtin_popcountll(ans))ans=res2;
} signed main(){
n=read<int>(),m=read<int>(),p=read<int>();
limit=(n+1)>>1;
for(int i=1;i<=n;i++){
char c;
for(int j=0;j<m;j++){
cin>>c;
if(idx(c))a[i]|=(1ll<<j);
}
}
for(int t=1;t<=min(n,50ll);t++)work();
for(int i=0;i<m;i++)
((ans>>i)&1)?putchar('1'):putchar('0');
puts("");
return 0;
}

CF1523D Love-Hate的更多相关文章

  1. 2021record

    2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...

随机推荐

  1. Ollama开发指南

    安装必备工具 确保已安装以下软件的正确版本: CMake 3.24 或更高版本 Go 1.22 或更高版本 GCC 11.4.0 或更高版本 使用 Homebrew 安装这些工具(适用于macOS和L ...

  2. 快速了解Django:核心概念解析与实践指南

    title: 快速了解Django:核心概念解析与实践指南 date: 2024/5/1 20:31:41 updated: 2024/5/1 20:31:41 categories: 后端开发 ta ...

  3. CF-943(已更B-E)

    CF- 943(已更 B-E) D赛时没调出来(╬▔皿▔)╯,还有几分钟的时候反而把E过了,本来应该是上大分一场(⊙﹏⊙),等会会补G1 这假期要刷题,还要补文化课--后面有空的话更一下之前打的线下赛 ...

  4. ES_CCS/R(三):跨集群复制 Cross-cluster replication(CCR)

    跨集群复制(CCR)功能支持将远程集群中的索引复制到本地集群. 可以在一些常见的生产用例中使用此功能: 灾难恢复(DR)/高可用性(HA):如果主群集发生故障,则进行灾难恢复. 辅助群集可以用作热备份 ...

  5. Golang重复Rails Devise gem密码加密

    https://github.com/haimait/go-devise-encryptor package main import ( "fmt" //devisecrypto ...

  6. nim 4. 模块

    看了一下nim的模块系统,真的非常简洁. 1) 一个nim文件就是一个模块 2) 通过import 引入模块,引入的时候不需要带扩展名, 比如有个模块 mod1.nim,  引入的时候: import ...

  7. 在jeecg-boot中使用代码生成器&mybatis-plus

    一.代码生成器代码生成器-->jeecgOneGUI配置文件:resource/jeecg/jeecg_config.properties,修改目标生成的路径和包名数据库连接:resource/ ...

  8. vue中render函数和h函数

    "render"函数是Vue组件的一个重要方法,它用于描述组件的视图结构,并负责渲染虚拟DOM树."render"函数是一个JavaScript函数,它接受一个 ...

  9. 用 C 语言开发一门编程语言 — 变量元素设计

    目录 文章目录 目录 前文列表 变量 变量语法规则 变量的读取和存储 将变量加入 Lisp Value 体系 变量的计算 变量的定义与赋值 异常处理优化 源代码 前文列表 <用 C 语言开发一门 ...

  10. HTML——标签语法

    <标签名 属性1="属性值1" 属性2="属性值2"-->内容部分</标签名> <标签名 属性1="属性值1" ...