题目大意:给你$n$个不重复的数,其值域为$[0,2^k)$,问你至少需要将这$n$个数拆成多少个集合,使得它们互相不是对方的子集,并输出方案。

数据范围:$n≤10^6$,$k≤20$。

$MD$我场上都想了啥。。。。

我们显然有一种$O(3^k)$的做法,对于数字$x$,我们枚举其子集,设当前枚举到的子集为$u$,我们连一条$u->x$的边,然后跑一个拓扑排序,即可确定至少需要划分为多少个集合(我场上根本没在想拓扑排序。。。。)

然后,这个显然会$TLE+MLE$。

然后我们发现,若存在$u,v,w,$满足$u$是$v$的子集,$v$是$w$的子集,那么这种情况下,从$w$连边向$u$,其实是多余的。故对于数字$x$,我们只需要连接$u->x$,其中$u$^$x=2^p$。那么边的数量就成功降低至$2^k$。

时间复杂度:$O(nk)$。

 #include<bits/stdc++.h>
#define M 1100005
using namespace std;
struct edge{int u,next;}e[M*]={}; int head[M]={},use=;
void add(int x,int y){use++;e[use].u=y;e[use].next=head[x];head[x]=use;}
int n,k,id[M]={};
queue<int> q; int dfn[M]={},in[M]={};
int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++){
int x; scanf("%d",&x);
id[x]=i;
}
for(int i=;i<(<<k);i++){
for(int j=;j<k;j++)
if((i&(<<j))==) add(i,i^(<<j)),in[i^(<<j)]++;
}
q.push();
while(!q.empty()){
int u=q.front(); q.pop();
if(id[u]) dfn[u]++;
for(int i=head[u];i;i=e[i].next){
in[e[i].u]--;
dfn[e[i].u]=max(dfn[e[i].u],dfn[u]);
if(in[e[i].u]==) q.push(e[i].u);
}
}
cout<<<<endl;
cout<<dfn[(<<k)-]<<endl; for(int i=;i<=dfn[(<<k)-];i++){
int res=;
for(int j=;j<(<<k);j++) res+=(dfn[j]==i&&id[j]);
printf("%d ",res);
for(int j=;j<(<<k);j++) if(dfn[j]==i&&id[j]) printf("%d ",j);
printf("\n");
}
}

【洛谷P4934】 礼物,拓扑排序的更多相关文章

  1. 洛谷P1073 Tarjan + 拓扑排序 // 构造分层图

    https://www.luogu.org/problemnew/show/P1073 C国有 n n个大城市和 mm 条道路,每条道路连接这 nn个城市中的某两个城市.任意两个城市之间最多只有一条道 ...

  2. 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)

    洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...

  3. 【洛谷 P4934】 礼物 (位运算+DP)

    题目链接 位运算+\(DP\)=状压\(DP\)?(雾 \(a\&b>=min(a,b)\)在集合的意义上就是\(a\subseteq b\) 所以对每个数的子集向子集连一条边,然后答案 ...

  4. [NOIP2008] 提高组 洛谷P1155 双栈排序

    题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...

  5. 洛谷.3809.[模板]后缀排序(后缀数组 倍增) & 学习笔记

    题目链接 //输出ht见UOJ.35 #include<cstdio> #include<cstring> #include<algorithm> const in ...

  6. 洛谷P1155 双栈排序

    这题什么毒瘤......之前看一直没思路,然后心说写个暴搜看能有多少分,然后就A了??! 题意:给你一个n排列,求它们能不能通过双栈来完成排序.如果能输出最小字典序方案. [update]这里面加了一 ...

  7. 洛谷P4165 [SCOI2007]组队(排序 堆)

    题意 题目链接 Sol 跟我一起大喊:n方过百万,暴力踩标算! 一个很显然的思路是枚举\(H, S\)的最小值算,复杂度\(O(n^3)\) 我们可以把式子整理一下,变成 \[A H_i + B S_ ...

  8. 洛谷 P2824 [HEOI2016/TJOI2016]排序 解题报告

    P2824 [HEOI2016/TJOI2016]排序 题意: 有一个长度为\(n\)的1-n的排列\(m\)次操作 \((0,l,r)\)表示序列从\(l\)到\(r\)降序 \((1,l,r)\) ...

  9. 【洛谷 P3165】 [CQOI2014]排序机械臂 (Splay)

    题目链接 debug了\(N\)天没debug出来,原来是找后继的时候没有pushdown... 众所周知,,Splay中每个编号对应的节点的值是永远不会变的,因为所有旋转.翻转操作改变的都是父节点和 ...

随机推荐

  1. 【Java】Eclipse在线安装SVN插件

    安装环境 系统:win7系统 软件:eclipse(Mars.2 Release (4.5.2)) 安装步骤 1. 打开eclipse软件,点击菜单栏的help——>Install New So ...

  2. 2018.10.04 NOIP模拟 排队(组合数学)

    传送门 T2原题啊. 直接组合数学求出合法方案数,再除去一个(n+m)!(n+m)!(n+m)!: ans=0(n<m)ans=0(n<m)ans=0(n<m) ans=n+1−mn ...

  3. ArcGIS Desktop python Add-in 测试一个插件

    a)制作一个插件文件 先找到工作目录,双击运行makeaddin.py脚本.这个脚本拷贝所有插件需要的文件和文件夹并在工作目录形成一个压缩文件.该压缩文件名为工作目录名称加上".esriad ...

  4. 反编译 轻松调频 Android APP 下载“飞鱼秀”录音

    经常听“飞鱼秀”,但是由于时间的原因,只能听回放,但是轻松调频的APP做的有点儿... 听回放的时候经常会中断,还不能拖动进度条,就决定把录音下载下来听. 1.反编译apk(Android反编译过程见 ...

  5. MySQL Yum存储库 安装、升级、集群

    添加MySQL Yum存储库 首先,将MySQL Yum存储库添加到系统的存储库列表中.按着这些次序: 在http://dev.mysql.com/downloads/repo/yum/上转到MySQ ...

  6. (树的直径)LightOJ -- 1094

    链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88230#problem/C 求树的直径,这里只不过给每条边增加一个边长属性,变成 ...

  7. angular2+ 初理解

    一.Angular Module     1.angular 模块是一个类,它需要NgModule这个装饰器函数接受一个原数据对象作为参数来描述这个模块类属性.     其中最重要的属性有:      ...

  8. PAT甲 1006. Sign In and Sign Out (25) 2016-09-09 22:55 43人阅读 评论(0) 收藏

    1006. Sign In and Sign Out (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...

  9. c#获取word文件页数、字数

    引用命名空间:using Microsoft.Office.Interop.Word; //启动Word程序 Application myWordApp = new ApplicationClass( ...

  10. 一个简单的QQ隐藏图生成算法

    隐藏图不是什么新鲜的东西,具体表现在大部分社交软件中,预览图看到的是一张图,而点开后看到的又是另一张图.虽然很早就看到过这类图片,但是一直没有仔细研究过它的原理,今天思考了一下,发现挺有趣的,所以自己 ...