热门标签 | 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;
}


推荐阅读
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 判断数组是否全为0_连续子数组的最大和的解题思路及代码方法一_动态规划
    本文介绍了判断数组是否全为0以及求解连续子数组的最大和的解题思路及代码方法一,即动态规划。通过动态规划的方法,可以找出连续子数组的最大和,具体思路是尽量选择正数的部分,遇到负数则不选择进去,遇到正数则保留并继续考察。本文给出了状态定义和状态转移方程,并提供了具体的代码实现。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
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社区 版权所有