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

Codeforces1083CMaxMex

Description一棵\(N\)个节点的树,每个节点上都有互不相同的\([0,~N-1]\)的数。定义一条路径上的数的集合为\(S\),求一条路径使得\(Mex(S)\)最大。


Description

一棵\(N\)个节点的树, 每个节点上都有 互不相同的 \([0, ~N-1]\) 的数。

定义一条路径上的数的集合为 \(S\), 求一条路径使得 \(Mex(S)\) 最大。

带修改, \(M\) 次查询


Solution

用一棵权值线段树维护。

节点 \([L,R]\)存储信息:是否有一条路径包含 \([L,R]\) 内的所有数 以及 路径两个端点。

合并两个区间: 在\(4\)个点中 枚举新路径的端点, 然后判断另外两个点是否在路径上即可。

正解能 \(O(1)\) 合并, 然而这个解法需要\(O(logN)\)

所以总复杂度为 \(O(Nlog^2N)\)


Code

#include
#include
#include
#include
#include
#define up(a, b) (a = a > b ? a : b)
#define down(a, b) (a = a > b ? b : a)
#define cmax(a, b) (a > b ? a : b)
#define cmin(a, b) (a > b ? b : a)
#define Abs(a) ((a) > 0 ? (a) : -(a))
#define rd read()
#define db double
#define LL long long
using namespace std;
typedef pair P;
inline char nc(){
static char buf[1<<14],*p1=buf,*p2=buf;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,1<<14,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
char c=nc();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
while(c>='0'&&c<='9'){x=x*10+c-'0',c=nc();}
return x*f;
}
const int N = 2e5 + 5;
int n, m, a[N], b[N], f[N][20], dep[N];
int timer, tin[N], tout[N];
vector to[N];
void dfs(int u) {
tin[u] = ++timer; // dfs序
for (int i = 0, up = to[u].size(); i int nt = to[u][i];
if (nt == f[u][0])
continue;
dep[nt] = dep[u] + 1;
dfs(nt);
}
tout[u] = timer;
}
inline bool isanc(int u, int v) { // 判断u是否是v的祖先
return tin[u] <= tin[v] && tout[u] >= tout[v];
}
int getlca(int u, int v) {
if (isanc(u, v))
return u;
for (int i = 19; ~i; --i)
if (f[u][i] && (!isanc(f[u][i], v)))
u = f[u][i];
return f[u][0];
}
inline bool isondownpath(int u, P v) { //判断u是否是 竖直路径v() 上的点
return isanc(v.first, u) && isanc(u, v.second);
}
inline bool isonpath(int u, P v) { //判断u是否是 路径v()上的点
int lca = getlca(v.first, v.second);
return isondownpath(u, P(lca, v.second)) || isondownpath(u, P(lca, v.first));
}
P merge(P u, P v) { //合并两条路径
if (u.first == -1 || v.first == -1)
return P(-1, -1);
int g[4] = {u.first, u.second, v.first, v.second};
for (int i = 0; i <4; ++i) {
for (int j = i + 1; j <4; ++j) {
bool flag = true;
for (int k = 0; k <4; ++k) {
if (k != i && k != j && !isonpath(g[k], P(g[i], g[j])))
flag = false;
}
if (flag)
return P(g[i], g[j]);
}
}
return P(-1, -1);
}
namespace SegT {
#define mid ((l + r) >> 1)
#define lson u <<1
#define rson u <<1 | 1
P t[N <<2];
void build(int l, int r, int u) {
if (l == r) {
t[u].first = t[u].secOnd= b[l];
return;
}
build(l, mid, lson); build(mid + 1, r, rson);
t[u] = merge(t[lson], t[rson]);
}
void update(int c, int l, int r, int u) {
if (l == r) {
t[u].first = t[u].secOnd= b[l];
return;
}
if (c <= mid)
update(c, l, mid, lson);
else update(c, mid + 1, r, rson);
t[u] = merge(t[lson], t[rson]);
}
int query(int l, int r, int u, P tmp) {
if (l == r) {
if (tmp.first == -1)
return t[u].first != -1;
P g = merge(tmp, t[u]);
return g.first != -1;
}
P g = tmp.first == -1 ? t[lson] : merge(tmp, t[lson]);
if (g.first == -1)
return query(l, mid, lson, tmp);
else return mid - l + 1 + query(mid + 1, r, rson, g);
}
}using namespace SegT;
int main()
{
n = rd;
for (int i = 1; i <= n; ++i)
a[i] = rd + 1, b[a[i]] = i;
for (int i = 2; i <= n; ++i) {
int u = rd;
f[i][0] = u;
to[u].push_back(i);
to[i].push_back(u);
}
dep[1] = 1; dfs(1);
for (int i = 1; i <20; ++i)
for (int j = 1; j <= n; ++j)
f[j][i] = f[f[j][i - 1]][i - 1];
;
build(1, n, 1);
m = rd;
for (; m; --m) {
int typ = rd;
if (typ == 1) {
int u = rd, v = rd;
swap(a[u], a[v]);
swap(b[a[u]], b[a[v]]);
update(a[u], 1, n, 1);
update(a[v], 1, n, 1);
}
else printf("%d\n", query(1, n, 1, P(-1, -1)));
}
}

Max Mex



推荐阅读
  • linux网络子系统分析(二)—— 协议栈分层框架的建立
    目录一、综述二、INET的初始化2.1INET接口注册2.2抽象实体的建立2.3代码细节分析2.3.1socket参数三、其他协议3.1PF_PACKET3.2P ... [详细]
  • 问题描述现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能;在实际开发过程中 ... [详细]
  • Web动态服务器Python基本实现
    Web动态服务器Python基本实现 ... [详细]
  • Android与JUnit集成测试实践
    本文探讨了如何在Android项目中集成JUnit进行单元测试,并详细介绍了修改AndroidManifest.xml文件以支持测试的方法。 ... [详细]
  • 本文通过分析一个具体的案例,探讨了64位Linux系统对32位应用程序的兼容性问题。案例涉及OpenVPN客户端在64位系统上的异常行为,通过逐步排查和代码测试,最终定位到了与TUN/TAP设备相关的系统调用兼容性问题。 ... [详细]
  • 本题要求计算一组正整数的最小公倍数(LCM)。输入包括多组测试数据,每组数据首先给出一个正整数n,随后是n个正整数。 ... [详细]
  • 本文详细介绍了Oracle 11g中的创建表空间的方法,以及如何设置客户端和服务端的基本配置,包括用户管理、环境变量配置等。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 本文通过C++语言实现了一个递归算法,用于解析并计算数学表达式的值。该算法能够处理加法、减法、乘法和除法操作。 ... [详细]
  • 本文介绍了如何通过C#语言调用动态链接库(DLL)中的函数来实现IC卡的基本操作,包括初始化设备、设置密码模式、获取设备状态等,并详细展示了将TextBox中的数据写入IC卡的具体实现方法。 ... [详细]
  • 本文探讨了在SQL Server中处理几何类型列时遇到的INTERSECT操作限制,并提供了解决方案,包括通过转换数据类型和使用额外表结构的方法。 ... [详细]
  • 理解浏览器历史记录(2)hashchange、pushState
    阅读目录1.hashchange2.pushState本文也是一篇基础文章。继上文之后,本打算去研究pushState,偶然在一些信息中发现了锚点变 ... [详细]
  • 本文详细介绍了在Linux操作系统上安装和部署MySQL数据库的过程,包括必要的环境准备、安装步骤、配置优化及安全设置等内容。 ... [详细]
  • 深入理解:AJAX学习指南
    本文详细探讨了AJAX的基本概念、工作原理及其在现代Web开发中的应用,旨在为初学者提供全面的学习资料。 ... [详细]
  • 本文介绍如何手动实现一个字符串连接函数,该函数不依赖于C语言的标准字符串处理函数,如strcpy或strcat。函数原型为void concatenate(char *dest, char *src),其主要作用是将源字符串src追加到目标字符串dest的末尾。 ... [详细]
author-avatar
吻过彩虹的脸_378
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有