FJWC2019 子图 (三元环计数、四元环计数)
给定 n 个点和 m 条边的一张图和一个值 k ,求图中边数为 k 的联通子图个数 mod 1e9+7。
\(n \le 10^5, m \le 2 \times 10^5, 1 \le k \le 4\)。
观察到 k 的值贼小,考虑分类讨论
下面代码中du[]代表点的度数。(度 找不到比较好的英文,而这个拼音比较巨,所以du是我的代码习惯中里出现拼音的少数几中情况之一)
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAd8AAAEvCAYAAAAEkstBAABYG0lEQVR42u2dB5QVxdaFwQRiQgQUAwKiCKIiKBgRA+aAihlzVhSeAcEIglnBgEqUIMGMiAEBQVEEcwCR/BQVBXwKBn6J9c9XWNeenu4bJty5fXuftfYamBumu6q6dtWpc/ap8Pfff1cQogdTYOeddx4/jNpDfSEIZT3G165da+644w6z7777mq233trstNNOpkWLFqZv377GmdoqfagRNOEL6gtBSDq+27dvbypUqGDH+bhx48yiRYvM7Nmzzauvvmr2339/+9qwYcP0DIh8NeEL6gtBKI2xXadOHVOzZk2TzFatWmUJ+IorrtBzIPIt/UEYZqtXrzaa8EW+6gsh38b1SSedZOrVq2fSNQj46aef1rMg8i090h00aJA966hVq5YdYFtttZXZZZddTK9evYx7XxQnfFasQaa+F/kK8cW6devM/Pnz7VyXiVlS+eczakeRb4lI6c4777QDsHHjxqZPnz7m/ffft4Pq888/N6NGjTKHH364ff2cc86x72fQRmXCdw/ME088Ya688kpzyCGHmGuvvdaMHDlSJCzyFWI+pg888EDz5JNPBnr6cEPvtttugQTcsmVL061bNz0PIt/MweDCqlevbgdZKrczdsQRR1gS/vPPP7My6Eoy4a9Zs8Z+rl27dvaa99tvP3PjjTfa3X2HDh1sFCO/79Klix4gka8Q0zHNHMBmIsi1/NZbb5mbbrrJHHnkkUVef/311039+vX1PIh8iz/wzjjjjIxcLgMGDEi4acr6HLi4E74jXq7zoIMOSuo+2nHHHU2NGjX0EIl8hZjOgWE2ZcoUuzmZOnVqkdeWL19u5HoW+RZr0DVv3ty6k4tj999/f1YGXnEnfPdQ3XfffWndz9FHH50IuND4EPkK8TnzTUa+33zzjTnqqKMSx2069xX5lngS/fTTTzMOMvBb7dq1zYMPPlimg684Ez7vPffcc83BBx+c0f1suOGGZujQoXqYRL6Cdr729zNmzLCCG7vvvnuR1z/55BOz+eab63kQ+WY24HbeeWczfPjwEpHvTz/9VOa73+KSb6rVbJDNmzdPbiSRrxCzMb3tttua8ePHF5kP/vvf/5otttjCNG3aNHC+uP76680ll1yi50HkW3rnHBiBBryHAKVU+W5ERJdV9HOmEz7v69+/v9l7770Drxc3tFvRht0PDx0ScxorIl8h/8f0wIEDLclmaswV3333neYKkW/6g+21116zai5htnTpUjuwfv31V7Pxxhubl156KfS9559/vnXLlNWEXBzyveqqqwIXDX/88Ydp1qyZvbdZs2aFpg8oeV7kK8RvM3LPPfekTbxITRInomdB5JvRQOvdu3di4CSTUXOD8quvvgp9X6dOncxll12WU+R72mmnmQceeCDpihW91rDAq8cff1wPlchXiFnKJfNCz5490wrOrFixop4DkW/mEyjkkop8sT322MNGNSezHj16mLPOOiunyBfd1f/85z9JyXfJkiWBr5ELPGLECD1YMSRfJuHykFAVcmNsu+hl4mHee++9InPDc889Z+cOF3ylsSLyzXiQvfnmm4HRe17DLU0085gxY4zLmQ2yq6++2txwww05Rb641bfffvvA623SpIl9gKpWrWr++uuvQGLGPa0HKx7k6+17FmQcuUh+NJ5jm8AqFu1Dhgwx1apVs3OBF5Dyu+++m/AMqt1EvhmJTmCUyUoWcPXhhx9ackJWrUqVKoVkGP22ww47WLLLFfL1nuE4FS6vffTRR3ZVS7kwvxHxqGjn+JAv9zFx4kTToEGDIhMtim8E4mA8O+r//B7XlAwMmhMXLFhgfvnlFy3IRL7FJ9zff//ddO/e3RZKcBNMWNBRphF/uZhqRFSzy8HL5F6mTZumByzPydfFMzgvyDPPPFNkLEyaNMlGwLrxnS0tc6F8xgL9vHDhwiJjmzlUXjCRb8aE+7///c907drVkhCD64ADDrDnFi4dJ1XtylR20UUXmVNPPTXnyNeby8wZbjq22WabmYsvvljEGwPy5fpZhKYjwkJMQ7akVIXyGQt169Y17du317OfRkxEcRYjed0o5Jl5Xcq33HKLTRFi0qCCz4svvhgayfzss88Wi3hxx7hJqSzPP4o74bt7JGgsWV7vhAkT7OssJPTw5T/5cu1t27a1u950DY+Rolvzczwz/+moKfU86rynCBF53fDp5DjnNeF+++23Nq/VuZOpPMQZRrJzCj6/bNky+36kJjMxOoTPuYjAXJ3w3cAhb9e1Dfl5FJJw+b5A6TPxIF/GPK7F4siq4j0aPHiwxkkephctXrxYxwpJghEpw+rmSiR43b+ZQxEZSfVM5EVjeMtesQIhMs81BKlDqFJlEhjA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" alt="">
观察图片
k = 1,输出 m。 k = 2, 枚举点 2,组合数一下即可。
对于 k = 3 我们分为三种情况(按照图片顺序从左到右)
图(1) 我们枚举边 2--3 ,则答案为(du[2] - 1) * (du[3] - 1)。
图(2) 我们枚举点 2 ,组合数一下即可。
图(3) 则转化为三元环计数问题。
需要注意 图(1) 中 可能出现 1 和 4 重合的情况,恰好是一个三元环。每个三元环会被统计三次。所以需要减去 3 * 三元环数量。
所以最后我们需要减去 2 * 三元环数量。
对于 k = 4,我们分为五种情况(按照图片顺序从左到右)
先考虑图(3)是一个菊花比较简单,枚举点 2 直接组合数一下即可。
然后我们考虑图(2), 我们考虑枚举 边 2--3 ,则答案为 (du[2] - 2) * (du[3] - 1) + (du[2] - 1) * (du[3] - 2)。
注意到可能存在 1 号点 和 (4号点 或 5号点) 重合的情况,那么就变成了 图(4) 。每一种图 (4) 都会被统计两次,需要减去两次 图(4) 的方案总数。
然后我们考虑图(1)。 我们考虑枚举点 3, 再依次枚举它的出边。我们开个变量 tmp 维护 已经扫过的出边的另一端点的出边数量和,即 sum(du[i] - 1) (i 是扫过的出边连接的点) 每次我们将本次扫的 (du[i] - 1) 与 tmp 乘一下累加到答案然后把 (du[i] - 1) 加到 tmp 里。
这里 我们会有三种重合情况:(假设点 2 是之前枚举过的点, 点 4 是当前正在枚举的点)
- 点 5 和 点 1 重合。 那么图变成了四元环,即图(5)。每个四元环会在这里被统计四次,接下来需要 -= 4 * 四元环方案数。
- 点 5 和 点 2 重合,点 1 和点 4 不重合。 那么图变成了图(4)。每个 图(4) 会在这里被统计两次, 接下来需要 -= 2 * 四元环方案数。
- 点 5 和 点 2 重合,点 1 和点 4 重合。 那么图变成了一个三元环。每个三元环会在这里被统计三次,接下来需要 -= 3 * 三元环方案数。
然后考虑图(4)。图 4 是有一个三元环和一条边组成。我们考虑枚举点 2 , ans += 点 2 所在三元环数量 * (du[2] - 2) 。
考虑图(5)。图(5)是一个四元环计数。
现在我们把问题转化成了给定图求每个点所在三元环数量,以及四元环总数。三元环数量可以用给每个点三元环数量 / 3 来求出。
首先考虑求每个点所在三元环的数量。
这是常数比较大的 \(O(m \sqrt m)\) 的算法,另外还有 \(O(m \sqrt n)\) 的转化为有向图的常数较小的做法,没看太懂这里不解释
我们考虑把点分为两种,第一种是度数 \(du[x] \le \sqrt m\) 的,第二种是度数 \(du[x] > \sqrt m\) 的 (一下简称第一种点、第二种点)。
然后我们三元环分为两类,第一类是包含第一种点的三元环, 第二类是不包含第一种点的三元环(环上所有点都是第二种点)。
先考虑枚举所有第一种点 x, 我们考虑枚举所有无序出边对,然后我们就可以得到三个顶点 (x, y, z) 。我们可以维护一个 set ,然后直接判断这三个点是否构成三元环。 如果构成三元环我们考虑统计答案。 首先 对于所有第一类点,我们会枚举所有三元环,直接在枚举这个点时暴力统计贡献即可。 对于第二类点,假设 y 和 z 都是第二类点, 那么 (x, y, z) 这个三元环只会在此时被统计,我们将 ans[y]++, ans[z]++。 如果 y 和 z 中只有一个第二类点(假设y),那么三元环 (x, y, z) 会被枚举两次,其中 x 和 z 是第一类点。而 y 只能被统计一次,我们可以考虑当 x 的标号 小于 z 的标号时候将 ans[y]++ 以避免重复统计。这一部分的时间复杂度为 \(O(m \sqrt m)\),因为每条边最多只会作为第一条出边出现两次,而每个点 x 的出度是 \(O(\sqrt m)\) 级别的,所以第二条出边最多为 \(O(\sqrt m)\) 个,所以复杂度为 \(O(m \sqrt m)\) 。
然后我们考虑枚举第二类三元环。由于第二类点的个数 \(\le \sqrt m\) 个,我们考虑暴力 \(O({\sqrt m}^3) = O(m\sqrt m)\) 枚举三个点判断是否是三元环即可。
然后我们考虑四元环计数。
考虑枚举枚举点 1(设为 x), 并钦定它是标号最大的点(钦定2 3 4 号点的标号都比 1 号点小),然后我们枚举 4 号点(设为y),再枚举 与 4 号点相连的 3 号点(设为z, z != x)。我们考虑维护一个 cnt 数组,cnt[x] 表示 和 1 号点的距离为 2 的路径数量。 我们每次枚举到 z 的时候,前面已经有 cnt[z] 条路径与 x 相连了, 我们让 ans += cnt[z], 然后 cnt[z]++ 即可。
至于时间复杂度的证明,我们可以将点按照度数从小到大排序后重新标号跑一遍算法,时间复杂度为 \(O(m \sqrt m)\)。我并不会证。。。代码里偷懒忘了排序了,复杂度可能会被卡掉
大毒瘤代码
#include <cmath>
#include <cstdio>
#include <vector>
#include <unordered_set>
using namespace std;
const int xkj = 1000000007;
int n, m, k;
vector<int> out[100010];
unordered_set<int> hsh[100010];
int x[200010], y[200010], du[100010], swh[100010], fuck[100010], bucket[100010], cnt;
int Cx2(int x) { return x * (long long)(x - 1) % xkj * 500000004 % xkj; }
int Cx3(int x) { return x * (long long)(x - 1) % xkj * (x - 2) % xkj * 166666668 % xkj; }
int Cx4(int x) { return x * (long long)(x - 1) % xkj * (x - 2) % xkj * (x - 3) % xkj * 41666667 % xkj; }
void prepare_swh() //获取每个点三元环数量
{
for (int i = 1; i <= n; i++) du[i] = 0, swh[i] = 0;
for (int i = 1; i <= m; i++) du[x[i]]++, du[y[i]]++;
int sqm = sqrt(m + 0.233); cnt = 0;
for (int i = 1; i <= n; i++)
{
if (du[i] <= sqm) //暴力统计
{
int sz = out[i].size();
for (int j = 0; j < sz; j++)
{
for (int k = j + 1; k < sz; k++)
{
if (hsh[out[i][j]].count(out[i][k]))
{
swh[i]++;
if (du[out[i][j]] > sqm && du[out[i][k]] > sqm) swh[out[i][j]]++, swh[out[i][k]]++;
else
{
int x = out[i][j], y = out[i][k];
if (du[x] > sqm || du[y] > sqm)
{
if (du[x] <= sqm) swap(x, y);
if (i < y) swh[x]++;
}
}
}
}
}
}
else fuck[++cnt] = i;
}
for (int i = 1; i <= cnt; i++)
{
for (int j = i + 1; j <= cnt; j++)
{
if (hsh[fuck[i]].count(fuck[j]))
{
for (int k = j + 1; k <= cnt; k++)
{
if (hsh[fuck[j]].count(fuck[k]) && hsh[fuck[i]].count(fuck[k]))
{
swh[fuck[i]]++, swh[fuck[j]]++, swh[fuck[k]]++;
}
}
}
}
}
}
int qcnt()
{
int ans = 0;
for (int i = 1; i <= n; i++) ans = (ans + swh[i]) % xkj;
return ans * 333333336LL % xkj;
}
int qcnt2() //获取 sigma 每个点在多少个三元环内*(这个点的度数-2)
{
int ans = 0;
for (int i = 1; i <= n; i++) ans = (ans + swh[i] * (long long)(du[i] - 2) % xkj) % xkj;
return ans;
}
int qcnt3() //获取正方形
{
int ans = 0;
for (int i = 1; i <= n; i++)
{
for (int j : out[i]) if (j < i)
{
for (int k : out[j]) if (k < i)
{
ans = (ans + bucket[k]) % xkj;
bucket[k]++;
}
}
for (int j : out[i]) if (j < i)
{
for (int k : out[j]) if (k < i)
{
bucket[k]--;
}
}
}
return ans;
}
int main()
{
freopen("subgraph.in", "r", stdin), freopen("subgraph.out", "w", stdout);
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= m; i++)
{
scanf("%d%d", &x[i], &y[i]);
out[x[i]].push_back(y[i]), out[y[i]].push_back(x[i]);
hsh[x[i]].insert(y[i]), hsh[y[i]].insert(x[i]);
}
prepare_swh();
if (k == 1) { printf("%d\n", m); }
if (k == 2)
{
int ans = 0;
for (int i = 1; i <= n; i++) ans = (ans + Cx2(out[i].size())) % xkj; // []---[]---[]
printf("%d\n", ans);
}
if (k == 3)
{
int ans = 0;
for (int i = 1; i <= n; i++) ans = (ans + Cx3(out[i].size())) % xkj; // 菊花型
for (int i = 1; i <= m; i++) ans = (ans + (out[x[i]].size() - 1) * (long long)(out[y[i]].size() - 1) % xkj) % xkj; //链型+三元环*3
ans = (ans - 2 * qcnt()) % xkj;//三元环数量
ans = (ans + xkj) % xkj;
printf("%d\n", ans);
}
if (k == 4)
{
int ans = 0;
for (int i = 1; i <= n; i++) ans = (ans + Cx4(out[i].size())) % xkj; // 菊花型
for (int i = 1; i <= m; i++) ans = (ans + Cx2(out[x[i]].size() - 1) * (long long)(out[y[i]].size() - 1) % xkj) % xkj,
ans = (ans + Cx2(out[y[i]].size() - 1) * (long long)(out[x[i]].size() - 1) % xkj) % xkj; //箭头形+陷阱型*2
ans = (ans + xkj - 3 * (long long)qcnt2() % xkj) % xkj; //减去陷阱型
for (int i = 1; i <= n; i++) //链型
{
int tmp = 0;
for (int j : out[i])
{
int tmp1 = out[j].size() - 1;
ans = (ans + tmp * (long long)tmp1 % xkj) % xkj;
tmp = (tmp + tmp1) % xkj;
}
}
ans = (ans + xkj - 3 * (long long)qcnt() % xkj) % xkj;
ans = (ans + xkj - 3 * (long long)qcnt3() % xkj) % xkj;
printf("%d\n", ans);
}
return 0;
}
FJWC2019 子图 (三元环计数、四元环计数)的更多相关文章
- [笔记] 三元环 && 四元环计数
Thanks to i207M && iki9! 三元环计数 无向图的三元环计数 我们首先需要对无向边按一定规则定向: 设 \(in[u]\) 表示 \(u\) 的度数 若 \(in[ ...
- Codeforces Round #360 (Div. 1) D. Dividing Kingdom II 并查集求奇偶元环
D. Dividing Kingdom II Long time ago, there was a great kingdom and it was being ruled by The Grea ...
- hdu3342-判断有向图中是否存在(至少)3元环或回路-拓扑排序
一:题目大意: 给你一个关系图,判断是否合法, 每个人都有师父和徒弟,可以有很多个: 不合法: 1) . 互为师徒:(有回路) 2) .你的师父是你徒弟的徒弟,或者说你的徒弟是你师父的 ...
- HDU3342:判断有向图中是否存在3元环-Tarjan或拓扑排序
题目大意: 给你一个关系图,判断是否合法.每个人都有师父和徒弟,可以有很多个: 若A是B的师父,B是C的师父,则A也算C的师父. 不合法: 1) . 互为师徒:(有回路) 2) .你的师父是你徒弟 ...
- 李洪强iOS开发之-环信02.2_环信官网下载环信 SDK
李洪强iOS开发之-环信02.2_环信官网下载环信 SDK 移动客服即时通讯云 iOS SDK 当前版本:V3.1.4 2016-07-08 [ 版本历史 ] | 开发指南 | 知识库 | Demo源 ...
- 李洪强iOS开发之-环信02.1_环信 SDK 2.x到3.0升级文档
李洪强iOS开发之-环信02.1_环信 SDK 2.x到3.0升级文档 SDK 2.x 至 3.0 升级指南 环信 SDK 3.0 升级文档 3.0 中的核心类为 EMClient 类,通过 EMCl ...
- 【Algorithm | 链表】单链表“环”、“环的起点”、“环的长度”问题
参考资料 • Floyd判圈算法 { 链接 } • 单链表“环”.“环的起点”.环的长度”问题 { 链接 } 链表环的问题 一.判断链表有换 使用两个指针slow和fast.两个指针开始时均在头节点处 ...
- 【编译原理】c++实现自下而上语法分析及中间代码(四元式)生成
写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...
- 编译原理 #04# 中缀表达式转化为四元式(JavaScript实现)
// 实验存档 运行截图: 代码中的总体转化流程:中缀表达式字符串→tokens→逆波兰tokens(即后缀表达式)→四元式. 由后缀表达式写出四元式非常容易,比较繁琐的地方在于中缀转逆波兰,这里采用 ...
随机推荐
- AE插件之SKYBOX CONVERTER
AE插件之SKYBOX CONVERTER AE插件SKYBOX CONVERTER的主要作用是开发全景视频或者制作全景图片时,对添加的字幕.图片进行扭曲. 下载目录:http://www.gfxca ...
- C++加载位图跟SOCKET通信的编写
//将屏幕信息转换为位图结构 CDC *pDeskDC=GetDesktopWindow()->GetDC();//获取桌面的额画图对象 ; ; CDC memDC;//定义一个内存画布 mem ...
- CentOS Firewall简单使用
启动 systemctl start firewalld 停止 systemctl stop firewalld 获取 firewalld 状态 firewall-cmd --state 在不改变状态 ...
- linux中ftp配置文件详解
vsftpd配置文件采用"#"作为注释符,以"#"开头的行和空白行在解析时将被忽略,其余的行被视为配置命令行,每个配置命令的"="两边不要留 ...
- Java多线程-线程的调度(优先级)
与线程休眠类似,线程的优先级仍然无法保障线程的执行次序.只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行. 线程的优先级用1-10之间的整数表示,数值越大优先级越高,默认的优先 ...
- idea maven项目依赖项有红色波浪线
在maven面板选中所有报错的maven项目,右键选择移除(remove),之后重新添加.
- 修改Tomcat可支持get传参方式的url长度,get形式
maxHttpHeaderSize="8192"加在 <Connector port="8081" maxHttpHeaderSize="314 ...
- win7安装linux双系统
整体流程大概就是下载启动盘制作工具以及linux镜像,这些步骤网上很多,我就不再重复了 这里以centos举例说几个我踩到的坑吧 1.选择开始安装后提示 Warning: /dev/root does ...
- SQL Server误区30日谈 第26天 SQL Server中存在真正的“事务嵌套”
误区 #26: SQL Server中存在真正的“事务嵌套”错误 嵌套事务可不会像其语法表现的那样看起来允许事务嵌套.我真不知道为什么有人会这样写代码,我唯一能够想到的就是某个哥们对SQL Serve ...
- 10. Regular Expression Matching字符串.*匹配
[抄题]: Given an input string (s) and a pattern (p), implement regular expression matching with suppor ...