CF2023C C+K+S 题解
题面
给您两个强联通的 \(^{\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 题解的更多相关文章
- OJ2237第k小数题解
题目描述: 有n个数,请你找出第k小的数. 输入描述: 第一行有2个正整数n,k(n,k<=10^7)第二行有n个非负数ai(ai<=10^5) 输出描述: 输出第k小的数. 输入样例: ...
- 9.1练习题5 差k素数对 题解
题目出处:洛谷 P1348 ,题面略有改编. 题目描述 给你两个数 n 和 k ,请求出所有小于等于 n 的相差为 k 的素数对. 输入格式 两个正整数n,k.1<=k<=n<=10 ...
- 排序入门练习题3 谁考了第k名 题解
题目出处:<信息学奥赛一本通>第二章 上机练习1 题目描述 在一次考试中,每个学生的成绩都不相同,现知道了每个学生的学号和成绩,求考第k名的学生的学号和成绩. 输入格式 输入的第一行包含两 ...
- 洛谷 P2105 K皇后 题解
START: 2021-08-06 16:34:44 题目链接: https://www.luogu.com.cn/problem/P2105 题目详情: 小 Z 最近捡到了一个棋盘,他想在棋盘上摆放 ...
- ABC267G Increasing K Times 题解
做这道题,很有感悟,发篇文. 先给数列从小到大排个序. 接下来设 \(f_{i,j}\) 表示前 \(i\) 个数的排列形成 \(j\) 个上坡的方案数. 接下来考虑转移,分为插入第 \(i\) 个数 ...
- 2018ICPC网络赛(焦作站)K题题解
一.题目链接 https://nanti.jisuanke.com/t/31720 二.题意 给$N$种船只,第$i$种船的载重量是$V_i$,数量是$2^{C_i}-1$.接下来有$Q$次询问,每次 ...
- 2018HPU暑期集训第四次积分训练赛 K - 方框 题解(图形打印)
思路分析:题目已经明确透露了这道题的解法:就是画框.当 输入的边长 的话,就表示可以在内层继续嵌套一个方框.废话就不多说了,直接上代码吧! 代码如下: #include <iostream&g ...
- POJ2104 区间第k小
题意就是区间第k大…… 题解: 前段时间用主席树搞掉了…… 如今看到划分树,是在想来写一遍,结果18号对着学长的代码调了一上午连样例都没过,好桑心…… 今天在做NOI2010超级钢琴,忽然发现用划分树 ...
- Codeforces Round #460 (Div. 2) ABCDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8397685.html 2018-02-01 $A$ 题意概括 你要买$m$斤水果,现在有$n$个超市让你选择. ...
- 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 ...
随机推荐
- 浅谈下javascript的proxy和reflect
近日喜欢上了uniapp和vue,但看到相关程序代码中频繁出现了proxy和reflect的使用,于是进行了一番学习,现总结如下. Proxy和Reflect是ES6(ECMAScript 2015) ...
- JS的可选链操作符(?.)与双问号(??),你用到了吗?
可选链操作符(?.) 以前一般这样使用: let nestedProp = obj.first && obj.first.second; 或者这样: let temp = obj.fi ...
- JAVAEE——tomcat安装
一.下载 1.网址:Tomcat官网 选择版本:点击左边Download下的which version,根据Supported Java Versions来选择合适的Tomcat版本 下载软件:点击左 ...
- 5G网元功能与接口
5G网元功能与接口 5G移动通信整体网络架构 5G网络功能之间的信息交互可以基于两种方式表示:其一为基于服务表示:其二为基于点对点表示.实时部署时,也可以采用两种方式相结合的表示方式. 并不是所有的接 ...
- QT原理与源码分析之如何开发一个自定义的绘图设备和QT绘图引擎?
简介 本文将介绍如何自定义QT绘图设备类和如何自定义QT绘图引擎类. 目录 QT绘图设备抽象类QPaintDevice QT绘图引擎抽象类QPaintEngine 自定义绘图设备类 自定义绘图引擎类 ...
- 【linux】【docker】Docker默认网段配置导致无法访问
背景 集团有N个基地,所有基地的网络使用的是172.x.x.x网段,这本身没有什么问题!但Docker默认的桥接网段也是172.17.x.x的,如果不修改docker的默认配置会导致个别基地无法访问! ...
- C# 开源浏览器性能提升,体验Chrome级速度
前言 使用 C# 和 CefSharp 开发的全功能网页浏览器. 项目介绍 SharpBrowser 是目前最快的开源 C# 网页浏览器! 采用了轻量级的 CEF 渲染器,在呈现网页时甚至比 Goog ...
- 《华为云DTSE》期刊免费下载:10个案例读懂云上架构升级策略
本文分享自华为云社区<<华为云DTSE>期刊第四期赋能云专刊,赋能云场景下DTSE服务各类开发者的案例分享>,作者:HuaweiCloudDeveloper. 把公司的开发者平 ...
- 什么是 RBAC 权限控制
RBAC是Role Based Access Control的英文缩写,意思是 基于角色的访问控制. RBAC实际上就是针对产品去挖掘需求时所用到的Who(角色).What(拥有什么资源).How(有 ...
- day11-基本运算符
运算符 java语言支持如下运算符: 优先级 ( 多敲,多练习 ) 算术运算符:+,-,*,/,%(模运算:取余),++,-- package operator; public class De ...