「题解」CF1468M Similar Sets
本文将同步发布于:
题目
题意简述
给定 \(n\) 个集合 \(S_{1\sim n}\),问是否存在 \(i,j\) 满足 \(i\neq j\) 且 \(\left\lvert S_i\cap S_j\right\rvert\geq 2\)。
若存在,输出 \(i,j\)(任意一对都可);否则输出 \(-1\)。
\(n\leq 10^5\),\(\sum\limits_{i=1}^n\left\lvert S_i\right\rvert\leq 2\times 10^5\)。
题解
图论转化
直接思考有点难,考虑经典套路,我们把这个问题转化成二分图模型。
对于一个集合 \(S_i\),我们将其构造为一个左部点 \(i\)。
对于一个元素 \(x\),我们将其构造为一个右部点 \(x\)。
如果 \(x\in S_i\),那么图上有一条边 \((i,x)\)。
那么 \(\left\lvert S_i\cap S_j\right\rvert\geq 2\),就对应有至少两个右部点连到了同样的两个点。
换句话说,符合条件的答案对应了图中的一个四元环。
并且,这张图的度数总和为 \(\sum\limits_{i=1}^n\left\lvert S_i\right\rvert\)。
按点的度数分治
现在我们要解决的问题就是一个二分图内是否存在四元环。
这同样是一个简单的问题,具体地,我们考虑按点的度数分治:
- 找到一个非负整数 \(B\);
- 称度数 \(\geq B\) 的为大点,度数 \(< B\) 的为小点;
- 对于大点,其个数为 \(\Theta\left(\frac{\sum\texttt{deg}}{B}\right)\)。
我们对于每个大左部点,标记其所有相连点,如果存在另一个左部点,其连接的标记点个数 \(\geq 2\),那么存在一个四元环。
我们对于每个小左部点,我们枚举其对应的所有的右部点对,然后对于每一个点对,我们枚举其最小值,然后标记其对应点,如果一个点在之前被标记过,那么就存在一个四元环。
根据上面的分析,我们得出算法的时间复杂度为 \(\Theta\left(\frac{\sum\texttt{deg}}{B}\sum\texttt{deg}+B\sum\texttt{deg}\right)\)。
理论分析可以得出,最优的时间复杂度为 \(\Theta\left(\sum\texttt{deg}\sqrt{\sum\texttt{deg}}\right)\)。
参考程序
#include<bits/stdc++.h>
using namespace std;
#define reg register
typedef long long ll;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
static char buf[1<<21],*p1=buf,*p2=buf;
#define flush() (fwrite(wbuf,1,wp1,stdout),wp1=0)
#define putchar(c) (wp1==wp2&&(flush(),0),wbuf[wp1++]=c)
static char wbuf[1<<21];int wp1;const int wp2=1<<21;
inline int read(void){
reg char ch=getchar();
reg int res=0;
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) res=10*res+(ch^'0'),ch=getchar();
return res;
}
inline void write(reg int x){
static char buf[32];
reg int p=-1;
if(x<0) x=-x,putchar('-');
if(!x) putchar('0');
else while(x) buf[++p]=(x%10)^'0',x/=10;
while(~p) putchar(buf[p--]);
return;
}
const int MAXN=1e5+5;
const int MAXS=2e5+5;
struct Event{
int x,y,id;
inline Event(reg int x=0,reg int y=0,reg int id=0):x(x),y(y),id(id){
return;
}
};
struct Link{
int val,id;
inline Link(reg int val=0,reg int id=0):val(val),id(id){
return;
}
};
int n;
inline pair<int,int> solve(void){
n=read();
reg int sum=0;
vector<vector<int>> S(n+1);
vector<int> V;
for(reg int i=1;i<=n;++i){
reg int k=read();
sum+=k;
S[i].resize(k);
for(reg int j=0;j<k;++j)
S[i][j]=read(),V.push_back(S[i][j]);
}
sort(V.begin(),V.end()),V.erase(unique(V.begin(),V.end()),V.end());
for(reg int i=1;i<=n;++i)
for(int& x:S[i])
x=lower_bound(V.begin(),V.end(),x)-V.begin();
reg int m=V.size();
reg size_t B=sqrt(sum/16);
vector<int> Big,Sma;
for(int i=1;i<=n;++i)
if(S[i].size()>=B)
Big.push_back(i);
else
Sma.push_back(i);
vector<bool> vis(m);
vis.resize(m);
for(reg int i=0,siz=Big.size();i<siz;++i){
int u=Big[i];
for(int x:S[u])
vis[x]=true;
for(reg int j=1;j<=n;++j){
int v=j;
if(u!=v){
reg int cnt=0;
for(int x:S[v])
if(vis[x])
++cnt;
if(cnt>=2)
return make_pair(u,v);
}
}
for(int x:S[u])
vis[x]=false;
}
vector<Event> E;
for(reg int i=0,siz=Sma.size();i<siz;++i){
reg int u=Sma[i];
for(reg int j=0,siz=S[u].size();j<siz;++j)
for(reg int k=j+1;k<siz;++k)
E.push_back(Event(S[u][j],S[u][k],u));
}
vector<vector<Link>> G;
G.resize(m);
for(Event e:E)
if(e.x<e.y)
G[e.x].push_back(Link(e.y,e.id));
else
G[e.y].push_back(Link(e.x,e.id));
vector<int> from;
from.resize(m);
for(reg int i=0;i<m;++i){
for(Link L:G[i])
if(!from[L.val])
from[L.val]=L.id;
else
return make_pair(from[L.val],L.id);
for(Link L:G[i])
from[L.val]=0;
}
return make_pair(-1,-1);
}
int main(void){
reg int t=read();
while(t--){
static pair<int,int> ans;
ans=solve();
if(ans.first==-1)
write(-1),putchar('\n');
else
write(ans.first),putchar(' '),write(ans.second),putchar('\n');
}
flush();
return 0;
}
「题解」CF1468M Similar Sets的更多相关文章
- 「题解」「美团 CodeM 资格赛」跳格子
目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...
- 「题解」「HNOI2013」切糕
文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...
- 「题解」JOIOI 王国
「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...
- 「题解」:[loj2763][JOI2013]现代豪宅
问题 A: 现代豪宅 时间限制: 1 Sec 内存限制: 256 MB 题面 题目描述 (题目译自 $JOI 2013 Final T3$「現代的な屋敷」) 你在某个很大的豪宅里迷路了.这个豪宅由东 ...
- 「题解」:$Six$
问题 A: Six 时间限制: 1 Sec 内存限制: 512 MB 题面 题面谢绝公开. 题解 来写一篇正经的题解. 每一个数对于答案的贡献与数本身无关,只与它包含了哪几个质因数有关. 所以考虑二 ...
- 「题解」:$Smooth$
问题 A: Smooth 时间限制: 1 Sec 内存限制: 512 MB 题面 题面谢绝公开. 题解 维护一个队列,开15个指针,对应前15个素数. 对于每一次添加数字,暴扫15个指针,将指针对应 ...
- 「题解」:Kill
问题 A: Kill 时间限制: 1 Sec 内存限制: 256 MB 题面 题面谢绝公开. 题解 80%算法 赛时并没有想到正解,而是选择了另一种正确性较对的贪心验证. 对于每一个怪,我们定义它的 ...
- 「题解」:y
问题 B: y 时间限制: 1 Sec 内存限制: 256 MB 题面 题面谢绝公开. 题解 考虑双向搜索. 定义$cal_{i,j,k}$表示当前已经搜索状态中是否存在长度为i,终点为j,搜索过边 ...
- 「题解」:x
问题 A: x 时间限制: 1 Sec 内存限制: 256 MB 题面 题面谢绝公开. 题解 赛时想到了正解并且对拍了很久.对拍没挂,但是评测姬表示我w0了……一脸懵逼. 不难证明,如果对于两个数字 ...
随机推荐
- Supervisord远程命令执行漏洞(CVE-2017-11610)
目录 Supervisor 漏洞复现 修复建议 Supervisor Supervisor是使用Python 开发的进程管理程序,一般使用命令行进行管理,当然也能通过web接口图形化管理服务.在配置了 ...
- Docker网络配置进阶
Docker启动会默认创建docker0虚拟网桥,是Linux的一个bridge,可以理解成一个软件交换机.它会在挂载到它的网口之间进行转发. 之后所有容器都是在172.17.0.x的网段上,并且可以 ...
- 『动善时』JMeter基础 — 7、jmeter.properties文件常用配置
目录 1.默认语言设置 2.配置默认编码格式 3.GUI图标放大比例设置 4.功能区工具栏图标大小设置 5.视图区目录树图标大小设置 6.内容区编辑字体设置 7.添加JMeter元素快捷键设置 8.捕 ...
- 【Linux】在centos中使用命令安装redis
1.前提centos能够上网 测试方式输入命令,有数据返回即可.如果则先配置centos网络连接. ping www.baidu.com 2.安装gcc 输入命令进行安装 yum install gc ...
- Mybatis最终搭建
框架搭建的流程1. 导入jar2. 准备属性文件和配置文件3. 编写数据库的表和类4. 为类编写一个XxxMapper接口5. 编写接口对应的映射文件XxxMapper.xml6. 根据接口的方法, ...
- .NET平台系列5 .NET Core 简介
系列目录 [已更新最新开发文章,点击查看详细] 自1995年互联网战略日以来最雄心勃勃的事业 -- 微软.NET战略, 2000年6月30日. 微软公司于2002年2月13日正式推出第一代.N ...
- (10)MySQL进阶篇SQL优化(InnoDB锁-间隙锁)
1.概述 当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁:对于键值在条件范围内但并不存在的记录,叫做"间隙(GAP)&quo ...
- TypeScript 中限制对象键名的取值范围
当我们使用 TypeScript 时,我们想利用它提供的类型系统限制代码的方方面面,对象的键值,也不例外. 譬如我们有个对象存储每个年级的人名,类型大概长这样: type Students = Rec ...
- 初探DBSCAN聚类算法
DBSCAN介绍 一种基于密度的聚类算法 他最大的优势是可以发现任意形状的聚类簇,而传统的聚类算法只能使用凸的样本聚集类 两个参数: 邻域半径R和最少点数目minpoints. 当邻域半径R内的点的个 ...
- 烽火SATA SSD DSS200-B
烽火SATA SSD DSS200-B 运营商用户 > 产品与解决方案 > 产品 烽火SATA SSD DSS200-B 烽火通信 DSS200-B 2.5" SATA SSD ...