热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[LOJ3140][COI2019]TENIS

神奇滴很的结论题。若选手\(u\)能够在至少一个场地战胜选手\(v\),则连一条\((u,v)\)的有向边。选手\(u\)能够获胜即从点\(u\)出发能到达其他所有结点。我们把强连

神奇滴很的结论题。

若选手 \(u\) 能够在至少一个场地战胜选手 \(v\),则连一条 \((u, v)\) 的有向边。选手 \(u\) 能够获胜即从点 \(u\) 出发能到达其他所有结点。

我们把强连通分量缩成一个点,由于该图类似竞赛图,容易发现缩完点后构成了一条有向链,每一个结点都向它后面的所有结点连边。

显然,有且仅有链头的强连通分量内的点能够获胜。

考虑同一个强连通分量内的点对应到给出的三个数组上有什么性质。

手玩发现,强连通分量纵向地划分了这三个数组。

给三个数组间相同的数连边,可以发现划分的位置就是没有边经过的位置。

考虑证明该性质。

对于链上相邻两个强连通分量,靠前的强连通分量中的每个点一定在三个数组中都位于靠后的强连通分量中每个点的前面。即它们在链上一定会形成一个划分。

同时,不难证明每一个划分两侧的点都属于不同的强连通分量。

所以该性质得证。

所以我们只需找出三个数组中第一个没有被边经过的间隙即可回答询问。

由于带修,所以用线段树实现。

#include
using namespace std;
const int MAXN = 1e5 + 10;
int n, m, rk[MAXN][3], mn[MAXN * 4], tag[MAXN * 4];
inline int ls(int p) { return p <<1; }
inline int rs(int p) { return p <<1 | 1; }
inline void push_up(int p) { mn[p] = min(mn[ls(p)], mn[rs(p)]); }
inline void get_down(int p, int x) { mn[p] += x, tag[p] += x; }
inline void push_down(int p) {
if (!tag[p]) return;
get_down(ls(p), tag[p]);
get_down(rs(p), tag[p]);
tag[p] = 0;
}
void update(int p, int l, int r, int ql, int qr, int x) {
if (ql <= l && r <= qr) {
get_down(p, x);
return;
}
push_down(p);
int mid = (l + r) >> 1;
if (ql <= mid) update(ls(p), l, mid, ql, qr, x);
if (qr > mid) update(rs(p), mid + 1, r, ql, qr, x);
push_up(p);
}
int find(int p, int l, int r) {
if (l == r) return l;
push_down(p);
int mid = (l + r) >> 1;
if (mn[ls(p)]) return find(rs(p), mid + 1, r);
return find(ls(p), l, mid);
}
void add(int x, int y) {
int l = *min_element(rk[x], rk[x] + 3), r = *max_element(rk[x], rk[x] + 3);
if (l != r) update(1, 1, n, l, r - 1, y);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
for (int j = 0, x; j <3; ++j)
for (int i = 1; i <= n; ++i) cin >> x, rk[x][j] = i;
for (int i = 1; i <= n; ++i) add(i, 1);
while (m--) {
int typ;
cin >> typ;
if (typ == 1) {
int x;
cin >> x;
cout <<(rk[x][0] <= find(1, 1, n) ? "DA" : "NE") <<"\n";
} else {
int p, u, v;
cin >> p >> u >> v, --p;
add(u, -1), add(v, -1);
swap(rk[u][p], rk[v][p]);
add(u, 1), add(v, 1);
}
}
return 0;
}


推荐阅读
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • Python 异步编程:深入理解 asyncio 库(上)
    本文介绍了 Python 3.4 版本引入的标准库 asyncio,该库为异步 IO 提供了强大的支持。我们将探讨为什么需要 asyncio,以及它如何简化并发编程的复杂性,并详细介绍其核心概念和使用方法。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
  • 本文探讨了《魔兽世界》中红蓝两方阵营在备战阶段的策略与实现方法,通过代码展示了双方如何根据资源和兵种特性进行战士生产。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • c# – UWP:BrightnessOverride StartOverride逻辑 ... [详细]
  • Yii 实现阿里云短信发送 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 文件描述符、文件句柄与打开文件之间的关联解析
    本文详细探讨了文件描述符、文件句柄和打开文件之间的关系,通过具体示例解释了它们在操作系统中的作用及其相互影响。 ... [详细]
  • 汇编语言等号伪指令解析:探究其陡峭的学习曲线
    汇编语言以其独特的特性和复杂的语法结构,一直被认为是编程领域中学习难度较高的语言之一。本文将探讨汇编语言中的等号伪指令及其对初学者带来的挑战,并结合社区反馈分析其学习曲线。 ... [详细]
author-avatar
三八依依2010
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有