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


推荐阅读
  • 2022年4月15日的算法练习题,包括最长公共子序列和线段树的应用。 ... [详细]
  • 正文♦时间复杂度:\(\mathcal{O}(n)\)思维题,不需要建树。设数组\(a\)记录每一个节点是否尊重它的父节点,数组\(b\)记录是否有节点尊重它,特别的,叶子节点必然 ... [详细]
  • C基本语法C程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。现在让我们简要地看一下什么是类、对象,方法、即时变量。对象-对象具有状态和行为 ... [详细]
  • 题目描述:给定 n 把雨伞和 m 个人,t 分钟后开始下雨。求在每个人只能使用一把雨伞的情况下,最多有多少人可以拿到雨伞。 ... [详细]
  • Activity跳转动画 无缝衔接
    Activity跳转动画 无缝衔接 ... [详细]
  • 题目描述墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令ÿ ... [详细]
  • HDU1085 捕获本·拉登!
    问题描述众所周知,本·拉登是一位臭名昭著的恐怖分子,他已失踪多年。但最近有报道称,他藏匿在中国杭州!虽然他躲在杭州的一个洞穴中不敢外出,但近年来他因无聊而沉迷于数学问题,并声称如果有人能解出他的题目,他就自首。 ... [详细]
  • A1166 峰会区域安排问题(25分)PAT甲级 C++满分解析【图论】
    峰会是指国家元首或政府首脑之间的会议。合理安排峰会的休息区是一项复杂的工作,理想的情况是邀请的每位领导人都是彼此的直接朋友。 ... [详细]
  • 本文探讨了如何利用数组来构建二叉树,并介绍了通过队列实现的二叉树层次遍历方法。通过具体的C++代码示例,详细说明了构建及打印二叉树的过程。 ... [详细]
  • 本文探讨了Web API 2中特性的路由机制,特别是如何利用它来构建RESTful风格的URI。文章不仅介绍了基本的特性路由使用方法,还详细说明了如何通过特性路由进行API版本控制、HTTP方法的指定、路由前缀的应用以及路由约束的设置。 ... [详细]
  • 本文介绍了如何在React Native应用中获取组件的实际宽度和高度,并详细说明了屏幕单位(如dp)与像素(px)之间的转换方法。 ... [详细]
  • 本文详细介绍了PHP中的回调函数及其多种实现方式,包括函数字符串、匿名函数、类静态方法和类方法。同时,探讨了闭包的概念及其在PHP中的应用,通过实例展示了如何利用闭包访问外部变量。 ... [详细]
  • 本文探讨了Codeforces 580C题目——Kefa与公园的问题,深入分析了如何在给定条件下帮助Kefa找到合适的餐厅。 ... [详细]
  • 1.打印日历打印日历判断是否是闰年#include<stdio.h>inta[]{0,31,28,31,30,31,30,31,31 ... [详细]
  • ZOJ 2760 - 最大流问题
    题目链接:How Many Shortest Paths。题目描述:给定一个包含n个节点的有向图,通过一个n*n的矩阵来表示。矩阵中的a[i][j]值为-1表示从节点i到节点j无直接路径;否则,该值表示从i到j的路径长度。输入起点vs和终点vt,计算从vs到vt的所有不共享任何边的最短路径数量。如果起点和终点相同,则输出无穷大。 ... [详细]
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社区 版权所有