题面

给您两个强联通的 \(^{\dagger}\) 有向图,每个图都有精确的 \(n\) 个顶点,但可能有不同数量的边。仔细观察后,您发现了一个重要特征——这些图中任何一个环的长度都能被 \(k\) 除尽。

每个 \(2n\) 顶点都属于两种类型中的一种:传入或传出。每个顶点的类型都是已知的。

您需要确定是否有可能在两张图之间建立恰好 \(n\) 条有向边,从而满足以下四个条件:

  • 任何添加的边的两端都位于不同的图中。
  • 从每个传出顶点,正好有一条新增边传出。
  • 从每个传入顶点,正好有一条新增边进入。
  • 在生成的图中,任何环的长度都能被 \(k\) 整除。

\(^{\dagger}\) 强联通图是指从每个顶点到其他顶点都有一条路径的图。

题解

由于所有环的长度被 \(k\) 整除,我们可以对上面进行环染色,染色后两个图的每一个点一定是唯一对应一种颜色,同时也可以是这个颜色的轮换。

因为图是强连通的,所以两个图任意找一点跑 \(\mathtt{bfs}\) 即可染色,考虑如何连接两个图,如果两个度出入度不等,一定不存在,否则,如果一个图全部都是出点或入点,那么这个图一定存在,因为加边不会构成环。

接下来考虑剩余的情况如何求解,考虑把第一张图所有颜色为 \(k\) 的出点个数记录下来给 \(s[k+1]\),入点个数记录给 \(s[k-1]\),第二张图必定满足记录的数据可以通过轮换与 \(s\) 相同,考虑 \(\mathtt{KMP}\) 匹配即可,为了防止 \(\mathtt{KMP}\) 匹配产生混淆,给入点加 \(n\),出点加 \(1\) 可以保证结果一定不同。

参考代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5 + 10;
int n, m, k, a[N], b[N]; void solve()
{
int n, m, k;
cin >> n >> k;
vector<int> a(n), b(n);
vector<vector<int>> ea(n), eb(n);
for (int i = 0; i < n; i ++ ) cin >> a[i];
cin >> m;
for (int i = 1; i <= m; i ++ )
{
int x, y;
cin >> x >> y;
x -- , y -- ;
ea[x].push_back(y);
}
for (int i = 0; i < n; i ++ ) cin >> b[i];
cin >> m;
for (int i = 0; i < m; i ++ )
{
int x, y;
cin >> x >> y;
x -- , y -- ;
eb[x].push_back(y);
}
int cnt0 = count(a.begin(), a.end(), 0);
int cnt1 = count(b.begin(), b.end(), 1);
if (cnt0 != cnt1) return cout << "NO\n", void();
if (cnt0 == n || !cnt0) return cout << "YES\n", void();
vector<int> c1(n, -1), c2(n, -1);
queue<int> q;
q.push(0), c1[0] = 0;
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = 0; i < ea[u].size(); i ++ )
{
int j = ea[u][i];
if (c1[j] == -1)
{
c1[j] = (c1[u] + 1) % k;
q.push(j);
}
}
}
q.push(0), c2[0] = 0;
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = 0; i < eb[u].size(); i ++ )
{
int j = eb[u][i];
if (c2[j] == -1)
{
c2[j] = (c2[u] + 1) % k;
q.push(j);
}
}
}
vector<ll> s(k + 1), t(k + 1);
for (int i = 0; i < n; i ++ )
{
if (a[i]) s[(c1[i] + 1) % k + 1] += n;
else s[(c1[i] - 1 + k) % k + 1] += 1;
if (b[i]) t[c2[i] + 1] += 1;
else t[c2[i] + 1] += n;
}
for (int i = 1; i <= k; i ++ ) t.push_back(t[i]);
vector<int> ne(k * 2 + 1);
for (int i = 2, j = 0; i < s.size(); i ++ )
{
while (j && s[i] != s[j + 1]) j = ne[j];
if (s[i] == s[j + 1]) j ++ ;
ne[i] = j;
}
for (int i = 1, j = 0; i < t.size(); i ++ )
{
while (j && t[i] != s[j + 1]) j = ne[j];
if (t[i] == s[j + 1]) j ++ ;
if (j == k) return cout << "YES\n", void();
}
cout << "NO\n";
} int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T;
cin >> T;
while (T -- ) solve();
return 0;
}

CF2023C C+K+S 题解的更多相关文章

  1. OJ2237第k小数题解

    题目描述: 有n个数,请你找出第k小的数. 输入描述: 第一行有2个正整数n,k(n,k<=10^7)第二行有n个非负数ai(ai<=10^5) 输出描述: 输出第k小的数. 输入样例: ...

  2. 9.1练习题5 差k素数对 题解

    题目出处:洛谷 P1348 ,题面略有改编. 题目描述 给你两个数 n 和 k ,请求出所有小于等于 n 的相差为 k 的素数对. 输入格式 两个正整数n,k.1<=k<=n<=10 ...

  3. 排序入门练习题3 谁考了第k名 题解

    题目出处:<信息学奥赛一本通>第二章 上机练习1 题目描述 在一次考试中,每个学生的成绩都不相同,现知道了每个学生的学号和成绩,求考第k名的学生的学号和成绩. 输入格式 输入的第一行包含两 ...

  4. 洛谷 P2105 K皇后 题解

    START: 2021-08-06 16:34:44 题目链接: https://www.luogu.com.cn/problem/P2105 题目详情: 小 Z 最近捡到了一个棋盘,他想在棋盘上摆放 ...

  5. ABC267G Increasing K Times 题解

    做这道题,很有感悟,发篇文. 先给数列从小到大排个序. 接下来设 \(f_{i,j}\) 表示前 \(i\) 个数的排列形成 \(j\) 个上坡的方案数. 接下来考虑转移,分为插入第 \(i\) 个数 ...

  6. 2018ICPC网络赛(焦作站)K题题解

    一.题目链接 https://nanti.jisuanke.com/t/31720 二.题意 给$N$种船只,第$i$种船的载重量是$V_i$,数量是$2^{C_i}-1$.接下来有$Q$次询问,每次 ...

  7. 2018HPU暑期集训第四次积分训练赛 K - 方框 题解(图形打印)

    思路分析:题目已经明确透露了这道题的解法:就是画框.当 输入的边长  的话,就表示可以在内层继续嵌套一个方框.废话就不多说了,直接上代码吧! 代码如下: #include <iostream&g ...

  8. POJ2104 区间第k小

    题意就是区间第k大…… 题解: 前段时间用主席树搞掉了…… 如今看到划分树,是在想来写一遍,结果18号对着学长的代码调了一上午连样例都没过,好桑心…… 今天在做NOI2010超级钢琴,忽然发现用划分树 ...

  9. Codeforces Round #460 (Div. 2) ABCDE题解

    原文链接http://www.cnblogs.com/zhouzhendong/p/8397685.html 2018-02-01 $A$ 题意概括 你要买$m$斤水果,现在有$n$个超市让你选择. ...

  10. HDU 5977 Garden of Eden(点分治求点对路径颜色数为K)

    Problem Description When God made the first man, he put him on a beautiful garden, the Garden of Ede ...

随机推荐

  1. Diskpart 操作

    DiskPart 是 Windows 操作系统中的一个命令行工具,用于管理磁盘分区.它可以创建.删除.格式化和调整分区大小,还可以设置活动分区等.以下是一些常用的 DiskPart 命令和操作步骤. ...

  2. Docker 发布镜像

    发布镜像 在 Docker Hub 发布镜像 登陆到 Docker Hub docker login 标记镜像并推送到 Docker Hub docker tag <image>:< ...

  3. AI时代的信仰是什么

    信仰是人们内心深处的信念,是推动人类前进的驱动力.AI从几十年前的缓慢探索,到如今的飞速发展,是什么信仰在驱动这一切呢? 摩尔定律 聊起信仰,我就会想起信息时代的摩尔定律.摩尔定律是由英特尔联合创始人 ...

  4. JDBC,SQL注入,事务,C3P0于Druid连接池(最详细解析)

    JDBC JDBC(Java DataBase Connectivty,Java数据库连接)API,是一种用于执行Sql语句的Java API,可以为关系型数据库提供统一的访问,其由一组Java编写的 ...

  5. TypeScript – Get Started

    前言 我学 TypeScript 的时候是 Angular 2.0 beta 的年代... 现在 Angular 都快 14 了. 但由于已经有 1 年半没有写 Angular 和 TypeScrip ...

  6. 消毒 url 和 html (url encode and sanitizer html )

    更新: 2020-06-24 FromRoute vs FromQuery decode FromRoute 是不会 auto decode 的, query string 就会 这个是微软默认的设置 ...

  7. Figma 学习笔记 – Color

    大纲 Figma 的颜色是通过 FIll 实现的 (Fill 还有其它功能比如 fill 图片) 整体大概长这样, 我们一个一个看 颜色和 opacity

  8. IDEA更改远程git仓库地址

    前言 我们在使用IDEA开发时,一般会配置好对应的git仓库,这样就比较容易对代码进行控制以及协同开发.   但有时候,我们远程的仓库地址由于这样那样的原因,需要迁移(这在爱折腾的企业是常有的事情). ...

  9. 使用c++ onnxruntime构建项目出现的bug

    bug1:The given version [11] is not supported, only version 1 to 7 is supported in this build. 应该是加载了 ...

  10. 数据库运维实操优质文章分享(含Oracle、MySQL等) | 2023年3月刊

    本文为大家整理了墨天轮数据社区2023年3月发布的优质技术文章,主题涵盖Oracle.MySQL.PostgreSQL等数据库的基础安装配置操作.故障处理.性能优化等日常实践操作,以及概念梳理.常用脚 ...