P10304 [THUWC 2020] 道路修建

news/2024/11/19 23:38:55/文章来源:https://www.cnblogs.com/cjoierzdc/p/18555848

注意到 \(1\) 到一个 \(b\) 子树内的点 \(x\) 的路径可以拆成 \(1\to p\to q\to x\) 的形式,其中 \(1\to p\) 走树边,\(p\to q\) 为在点 \(p\) 从树边走出去,在点 \(q\) 走回来,然后 \(q\) 再走树边走到 \(x\)

考虑 \(f_i\) 为最小的 \(d\),满足断掉 \(i\) 深度为 \(d\) 的祖先到 \(i\) 的链后,\(1\) 仍然能到 \(i\)。那么一个点 \(x\) 能到达当且仅当存在 \(q\)\(b\to x\) 路径上,且 \(f_q\le dep_a\),即 \(\min\limits_{q\in path(b,x)}f_q\le dep_a\)

考虑怎么求 \(f\)。这个可以按照拓扑序从小往大枚举 \(u\),同时处理所有非树边 \(u\to v\),贡献为 \(u\)\(\operatorname{LCA}(u, v)\) 这条链上 \(f\) 的最大值。因为此时 \(u\to \operatorname{LCA}(u, v)\) 链上的 \(f\) 都已知,可以直接倍增。

现在我们已知了 \(f\),把每组询问挂在 \(b\) 上,动态维护 \(\min f\) 的权值线段树,不难线段树合并做到 \(O((n+m+q)\log n)\)

code
#include <bits/stdc++.h>
#define ALL(x) begin(x), end(x)
using namespace std;
void file() {freopen("1.in", "r", stdin);freopen("1.out", "w", stdout);
}
using ll = long long;
using PII = pair<int, int> ;const int kInf = 1e9;
const int kN = 1.5e5 + 5;int n, m, q;
array<int, kN> fa, ord, in, dep, f, ans;
array<bool, kN> intr, vis;
array<PII, kN> ed;
array<vector<PII>, kN> g, qry;
array<vector<int>, kN> tr, buc;
array<array<int, kN>, 20> jp, mn;void toposort() {for(int i = 1; i <= m; i++)in[ed[i].second]++;queue<int> q;for(int i = 1; i <= n; i++)if(!in[i]) q.push(i);int tot = 0;while(q.size()) {int x = q.front(); q.pop();ord[++tot] = x;for(auto k : g[x]) {int to = k.first;if(!--in[to]) q.push(to);}}
}void build() {for(int i = 1; i <= n; i++)sort(ALL(g[i]), greater<> ());dep[0] = -1;for(int i = 1, x = 1; i <= n; i++) {vis[x] = 1;for(bool flag = 0; x; x = fa[x]) {while(g[x].size()) {auto k = g[x].back(); g[x].pop_back();int to = k.first;if(vis[to]) continue;else {intr[k.second] = flag = 1;f[to] = dep[to] = dep[x] + 1, fa[to] = x;tr[x].push_back(to), x = to;break;}}if(flag) break;}}
}void init(int x) {mn[0][x] = f[x];for(int i = 1; i < 19; i++)mn[i][x] = min(mn[i - 1][x], mn[i - 1][jp[i - 1][x]]);
}
int lca(int x, int y) {if(dep[x] < dep[y]) swap(x, y);for(int i = 19; ~i; i--)if(dep[jp[i][x]] >= dep[y]) x = jp[i][x];if(x == y) return x;for(int i = 19; ~i; i--)if(jp[i][x] ^ jp[i][y])x = jp[i][x], y = jp[i][y];return fa[x];
}
int query(int anc, int x) {int ans = f[anc];for(int i = 19; ~i; i--)if(dep[jp[i][x]] >= dep[anc])ans = min(ans, mn[i][x]), x = jp[i][x];return ans;
}const int kS = 5e6 + 5;struct SGT {int tot = 0;array<int, kN> root;array<int, kS> ls, rs, sum;void pu(int o) { sum[o] = sum[ls[o]] + sum[rs[o]]; }void modify(int& o, int l, int r, int x, int v) {if(!o) o = ++tot;sum[o] += v;if(l == r) return ;int mid = (l + r) >> 1;if(mid < x) modify(rs[o], mid + 1, r, x, v);else modify(ls[o], l, mid, x, v);}void erase(int& o, int l, int r, int x, int y) {if((l > y) || (r < x)) return ;if((l >= x) && (r <= y)) return void(o = 0);int mid = (l + r) >> 1;erase(ls[o], l, mid, x, y);erase(rs[o], mid + 1, r, x, y);pu(o);}int query(int o, int l, int r, int x, int y) {if((l > y) || (r < x)) return 0;if((l >= x) && (r <= y)) return sum[o];int mid = (l + r) >> 1;return query(ls[o], l, mid, x, y) + query(rs[o], mid + 1, r, x, y);}int merge(int x, int y, int l, int r) {if(!x || !y) return x + y;sum[x] += sum[y];if(l == r) return x;int mid = (l + r) >> 1;ls[x] = merge(ls[x], ls[y], l, mid);rs[x] = merge(rs[x], rs[y], mid + 1, r);return x;}
}sgt;void dfs(int x) {for(int to : tr[x])dfs(to), sgt.root[x] = sgt.merge(sgt.root[x], sgt.root[to], 0, n);int sum = sgt.query(sgt.root[x], 0, n, f[x] + 1, n) + 1;sgt.erase(sgt.root[x], 0, n, f[x] + 1, n);sgt.modify(sgt.root[x], 0, n, f[x], sum);for(auto k : qry[x]) {int dep = k.first, id = k.second;ans[id] = sgt.query(sgt.root[x], 0, n, dep + 1, n);}
}int main() {// file();ios::sync_with_stdio(0), cin.tie(0);cin >> n >> m >> q;for(int i = 1, u, v; i <= m; i++) {cin >> u >> v;ed[i] = PII {u, v};g[u].emplace_back(v, i);}toposort(), build();for(int i = 1; i <= m; i++) {int u = ed[i].first, v = ed[i].second;if(!intr[i]) buc[u].push_back(v);}jp[0] = fa;for(int i = 1; i < 20; i++)for(int j = 1; j <= n; j++)jp[i][j] = jp[i - 1][jp[i - 1][j]];for(auto& k : mn) k.fill(kInf);for(int i = 1; i <= n; i++) {int x = ord[i]; init(x);for(int to : buc[x]) {int anc = lca(x, to);f[to] = min(f[to], query(anc, x));}}for(int i = 1, a, b; i <= q; i++) {cin >> a >> b;qry[b].emplace_back(dep[a], i);}dfs(1);for(int i = 1; i <= q; i++)cout << ans[i] << "\n";return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/837061.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

k8s阶段02 namespace,pod资源及命令, pod资源配置(应用监控,资源需求和限制), 多容器pod(初始容器), k8s卷基础

namespaceNamespace: 名称空间,命名空间资源对象名称隔离www.google.com, www.magedu.com资源类型:名称空间级别:必须属于某个名称空间-n NAMESPACE_NAME --namespace NAMESPACE_NAME集群级别:不属于任何名称名称 命令: kubectl get kubectl get TYPE [name, ...]…

三维地球--SparkGlobe

下载地址: 链接:https://pan.baidu.com/s/1Z-7UdVJvJL0jxLoGon79cQ 提取码:ehs5

学习笔记493—简单解释超声波成像的工作原理【全网最详细讲解!】

简单解释超声波成像的工作原理 我们将从以下几个方面进行讨论。请向下滚动,开始阅读。声音与超声波导论 发送和接收超声波 超声波与人体组织的相互作用 扫描方式:A扫描 扫描方式:B扫描 频率、波长、分辨率和深度 多普勒效应声音和超声波 我们都很熟悉声音。它帮助我们交流和…

2024-11-19--servelt与request

servelt urlPattern配置request请求

高级语言程序设计课程第八次个人作业

班级:https://edu.cnblogs.com/campus/fzu/2024C 作业要求: https://edu.cnblogs.com/campus/fzu/2024C/homework/13307 学号:102400121 姓名:林永庆 11.13 12 制表符是\t36712.9 1 函数传递的时候就是地址了,在函数中scanf的时候不用&2389 指向指针的指针总结:菜就多…

STM32F103系统时钟配置

时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。时钟系统就是CPU的脉搏,决定CPU速率,像人的心跳一样 只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理 (点灯,串口,ADC),时钟的重要性不言而喻。 一、…

20222318 2024-2025-1 《网络与系统攻防技术》实验六实验报告

1.实验内容 1.1 实验要求 掌握Metasploit的使用方法:“Search——Use——Show——Set——Exploit/run”。 1.2 实验任务 (1)前期渗透 (2)Vsftpd源码包后门漏洞(21端口) (3)SambaMS-RPC Shell命令注入漏洞(端口139) (4)Java RMI SERVER命令执行漏洞(1099端口) (…

atrace带ftrace数据如何转换成ftrace内容

第一种方法使用这个转换成ftrace数据 第二种方法 是的,systrace --from-file 是一种方便的方法,用于处理已经生成的 trace 文件(比如 systrace.html 或其他格式),包括提取或转换数据。以下是如何使用 systrace --from-file 来尝试转换为 ftrace 的详细方法。1. 什么是 sys…

10.7

Java有try-catch-finally的异常处理机制,包括以下几种情况:1、不抛出异常,try里面的代码、finally里面的代码、finally以后的代码都将正常执行,而catch里面的代码不会执行。2、抛出异常且被catch捕获,try里面的代码部分执行,catch里面的代码、finally里面的代码、finally…

排错:New-Object : 找不到类型 [Microsoft.Online.Administration.StrongAuthenticationRequirement]

前言今天,真的是被PowerShell坑的不要不要的!故事就不分享了,大家看看这个错误和解决方法吧。正文错误信息New-Object : 找不到类型 [Microsoft.Online.Administration.StrongAuthenticationRequirement]: 请确认加载了包含该类型的程序 集。 所在位置 行:1 字符: 8 + $SAR …

Github快速搭建个人/组织网站

最近课题组要建网站,记录一下速通流程。follow本流程你可以快速获得一个个人或组织的网站首页,部署在github的服务器上,完全免费。 预备工具 ke xue上网,从而登github 本地安装git 步骤 1 在自己的github账户建立空repo,必须命名为USRNAME.github.io (USRNAME是你的githu…

类和对象案例

第一道1.先写一个手机类,将属性和行为全部写完2,再写一个手机测试类,将其成员变量赋值 并不是只有测试类才能写main,其他类也可以有main,只不过代码会很臃肿,测试就用测试,不要把main写在其他类里总览第二道1.先写一个书类2.再写一个书测试类,将其成员变量赋值总览提供…