「NOI2021 D1T3 庆典」题解

news/2025/1/15 16:02:28/文章来源:https://www.cnblogs.com/ft61/p/18405507

uoj675

加强:\(\sum k\le6\times10^5\)


暴力

\(u\)\(s\Rightarrow t\) 路径上 \(\iff\) 正图上 \(s\Rightarrow u\) 且反图上 \(u\Rightarrow t\)

时间复杂度 \(O((n+m)q)\)

正解

只关心可达性,不妨 SCC 缩点成 DAG。注意到一个奇怪的条件:

对于三座城市 \(x,y,z\),若 \(x\Rightarrow z\)\(y\Rightarrow z\),那么有 \(x\Rightarrow y\)\(y\Rightarrow x\)

若存在边 \((x,z),(x,y),(y,z)\),可以删去边 \((x,z)\)。这样每个点的前驱唯一,又有原图弱连通,即为叶向树
实现上有两种做法:拓扑排序,保留每个点的最后一条入边;从零入度点开始 dfs,优先递归编号大的儿子,保留 dfs 树(利用 tarjan 缩点的性质)

叶向树

\(k=0\) \(t\)\(s\) 子树内时答案为深度差

\(k=1\) 只需要讨论走不走新边,转化为子树和根链求交

\(k=2\)

时间复杂度 \(O(n\log n+\sum k\log k)\)

#ifndef FT#define NDEBUG
#endif
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std; using namespace __gnu_pbds; using namespace __gnu_cxx;
#define For(i,x,y,...) for(int i=x,##__VA_ARGS__;i<=(y);++i)
#define rFor(i,x,y,...) for(int i=x,##__VA_ARGS__;i>=(y);--i)
#define Rep(i,x,y,...) for(int i=x,##__VA_ARGS__;i<(y);++i)
#define pb emplace_back
#define sz(a) int((a).size())
#define all(a) (a).begin(),(a).end()
#define fi first
#define se second
#define mkp make_pair
typedef long long LL; typedef vector<int> Vi; typedef pair<int,int> Pii;
auto ckmax=[](auto &x,auto y) { return x<y ? x=y,true : false; };
auto ckmin=[](auto &x,auto y) { return y<x ? x=y,true : false; };
sfmt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int l,int r) { return uniform_int_distribution<>(l,r)(mt); }
template<typename T=int>T read() { T x; cin>>x; return x; }const int mod = 998244353;
struct mint {int x; mint(int x=0):x(x<0?x+mod:x<mod?x:x-mod){}mint(LL y) { y%=mod, x=y<0?y+mod:y; }mint& operator += (const mint &y) { x=x+y.x<mod?x+y.x:x+y.x-mod; return *this; }mint& operator -= (const mint &y) { x=x<y.x?x-y.x+mod:x-y.x; return *this; }mint& operator *= (const mint &y) { x=1ll*x*y.x%mod; return *this; }friend mint operator + (mint x,const mint &y) { return x+=y; }friend mint operator - (mint x,const mint &y) { return x-=y; }friend mint operator * (mint x,const mint &y) { return x*=y; }
};	mint Pow(mint x,LL y=mod-2) { mint z(1);for(;y;y>>=1,x*=x)if(y&1)z*=x;return z; }const int N = 3e5+5;namespace T { // 叶向树
int n,rt,ind,val[N],sum[N],dfn[N],st[19][N];
Vi e[N];
int _min(int x,int y) { return dfn[x]<dfn[y] ? x : y; }
void dfs(int u,int fa) {dfn[u] = ++ind, st[0][ind] = fa, sum[u] = sum[fa] + val[u];for(int v : e[u]) dfs(v,u);
}
int lca(int u,int v) {if( u == v ) return u;if( (u=dfn[u]) > (v=dfn[v]) ) swap(u,v);int k = __lg(v-u++);return _min(st[k][u], st[k][v-(1<<k)+1]);
}
void main() {// cerr<<"T:\n"; For(i,1,n) for(int j : e[i]) cerr<<"  "<<i<<" "<<j<<'\n';dfs(rt,0);For(i,1,18) For(j,1,n-(1<<i)+1) st[i][j] = _min(st[i-1][j], st[i-1][j+(1<<i-1)]);
}
}namespace DAG {
int n,deg[N];
Vi e[N];
void main() {// cerr<<"DAG:\n"; For(i,1,n) for(int j : e[i]) cerr<<"  "<<i<<" "<<j<<'\n';T::n = n;For(i,1,n) for(int j : e[i]) ++deg[j];queue<int> q;For(i,1,n) if( !deg[i] ) q.emplace(i), T::rt = i;assert(sz(q)==1);while( sz(q) ) {int u = q.front(); q.pop();for(int v : e[u]) if( !--deg[v] ) q.emplace(v), T::e[u].pb(v);}
}
}namespace G { // 原图
int n,m,ind,dfn[N],low[N],id[N];
Vi e[N];
void tj(int u) {static int t,s[N];dfn[u] = low[u] = ++ind, id[u] = -1, s[++t] = u;for(int v : e[u])if( !dfn[v] ) tj(v), ckmin(low[u], low[v]);else if( !~id[v] ) ckmin(low[u], dfn[v]);if( dfn[u] == low[u] ) {++DAG::n;do id[s[t]] = DAG::n, ++T::val[DAG::n]; while( u != s[t--] );}
}
void main() {For(i,1,n) if( !dfn[i] ) tj(i);For(i,1,n) for(int j : e[i]) if( id[i] != id[j] ) DAG::e[id[i]].pb(id[j]);// cerr<<"id: "; For(i,1,n) cerr<<id[i]<<" "; cerr<<'\n';
}
}int mm;
Vi ver;
struct VT {int head[N];bool vis[N];struct { int nxt,to; } e[30];void clr() { for(int i : ver) head[i] = vis[i] = 0; }void dfs(int u) {if( vis[u] ) return; vis[u] = 1;for(int i = head[u], v; v = e[i].to, i; i = e[i].nxt) dfs(v);}
} g1,g2;
void adde(int x,int y) {g1.e[++mm] = {g1.head[x],y}, g1.head[x] = mm;g2.e[mm] = {g2.head[y],x}, g2.head[y] = mm;// cerr<<"  "<<x<<" "<<y<<" "<<'\n';
}void MAIN() {int q,k; cin>>G::n>>G::m>>q>>k; For(i,1,G::m, x,y) cin>>x>>y, G::e[x].pb(y);G::main(), DAG::main(), T::main();while( q-- ) {// cerr<<"VT:\n";int s,t; s = G::id[read()], t = G::id[read()], ver = {s,t};For(i,1,k, x,y)x = G::id[read()], y = G::id[read()],ver.pb(x), ver.pb(y), adde(x,y);auto cmp = [](int x,int y){return T::dfn[x]<T::dfn[y];};sort(all(ver),cmp), ver.erase(unique(all(ver)),ver.end());rFor(i,sz(ver)-1,1) ver.pb(T::lca(ver[i-1],ver[i]));ver.pb(T::rt), sort(all(ver),cmp), ver.erase(unique(all(ver)),ver.end());Rep(i,1,sz(ver)) adde(T::lca(ver[i-1],ver[i]),ver[i]);g1.dfs(s), g2.dfs(t);int ans = 0;for(int i : ver) if( g1.vis[i] && g2.vis[i] ) ans += T::val[i];For(i,k+1,mm) if(int x = g2.e[i].to, y = g1.e[i].to; g1.vis[x] && g2.vis[y] )ans += T::sum[T::st[0][T::dfn[y]]] - T::sum[x];cout<<ans<<'\n';g1.clr(), g2.clr(), mm = 0;}
} signed main() {
#ifdef FTfreopen("in","r",stdin); freopen("out","w",stdout);
#endifios::sync_with_stdio(0);cin.tie(0);int lft=1; while( lft-- ) {MAIN();}return 0;
}

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

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

相关文章

VS安装插件,按CTRL+鼠标左键进入函数

1。菜单栏-》工具-》扩展和更新 2.进入扩展和更新,点击联机,vs库,右上输入“Go To Definition” 3.搜索 出插件,选择作者是“Noah Richards” 4.下载安装重启即可hello,world~~~

【Azure Service Bus】创建 ServiceBus 的Terraform脚本报错GetAuthorizationRule: Invalid input

问题描述 在使用Terraform部署Service Bus时候,遇见了如下报错: Error: Error making Read request on Azure ServiceBus Topic Authorization Rule : servicebus.TopicsClient#GetAuthorizationRule: Invalid input: autorest/validation: validation failed: parameter=aut…

IIC工作模式时序分析

IIC工作模式时序分析 此处利用IO口模拟IIC通信过程中的时序。通信过程 在IIC通信过程SDA存在两种模式(接收模式和发送模式),发送或接受一个字节(器件的7个bit+1个bit方向(1 - 读方向,0 - 写方向)) 模式配置当SDA为接入模式接收了1字节数据后在第九个时钟脉冲期间就要变…

第四章 视图(views)

4.视图 4.1 文件or文件夹4.2 相对和绝对导入urls注意实现:不要再项目根目录做相对导入。 原则:绝对导入 相对导入(层级深)4.3 视图参数 urlpatterns = [path(login/, account.login, name="login"),path(auth/, order.auth, name=auth), ]from django.shortcuts …

[设计模式] Cola-StateMachine : 一个轻量实用的Java状态机框架

1 概述:状态机 1.0 状态机 vs 工作流在介绍状态机之前,先介绍一个工作流(WorkFlow),初学者通常容易将两个概念混淆。工作流(WorkFlow),大体是指业务过程(整体或者部分)在计算机应用环境下的自动化,是对工作流程及其各操作步骤之间业务规则的描述。在计算机系统中,工…

Qml 实现瀑布流布局

最近在刷掘金的时候看到一篇关于瀑布流布局的文章,然鹅他们的实现都是前端的那套,就想着 Qml 有没有类似实现。 结果百度了一圈也没有( T_T Qml 凉了凉了 ),于是,我按照自己理解,简单实现了一个 Qml 版的瀑布流布局。【写在前面】 最近在刷掘金的时候看到一篇关于瀑布流布…

Rocky9

Rocky Linux 9.4 部署Zabbix 7.0 1-1.检测源 wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm #下载epel的源 rpm -ivh epel-release-latest-8.noarch.rpm #epel安装 rpm -Uvh https://repo.zabbix.com/zabbix/7.0/rocky/9/x86_64/zabbix-releas…

洛谷题单指南-常见优化技巧-P1714 切蛋糕

原题链接:https://www.luogu.com.cn/problem/P1714 题意解读:求长度不超过m的最大子段和 解题思路: 1、暴力法 设a[N]表示原数组,s[N]是a[N]的前缀和,对于每一个元素s[i],计算其与前m个元素之差,取差值最大值,用代码表示: for(int i = 1; i <= n; i++) {for(int j …

【专题】2024年中国折叠屏手机市场与消费趋势研究报告合集PDF分享(附原数据表

原文链接:https://tecdat.cn/?p=37645 中国智能手机市场目前仍处于整体增长瓶颈期,增长复苏未达预期,消费者换机预期周期不断延长,使得行业对破局点的探寻更为紧迫。与此同时,中端消费者购机呈现出消费降级与升级的分化态势,不过更多人会选择体验更好、配置更优的产品以…

Goby 漏洞发布|(CVE-2024-45195)Apache OFBiz /viewdatafile 代码执行漏洞【已复现】

漏洞名称:Apache OFBiz /viewdatafile 代码执行漏洞(CVE-2024-45195) English Name:Apache OFBiz /viewdatafile Code Execution Vulnerability(CVE-2024-45195) CVSS core: 8.0 漏洞描述: Apache OFBiz是一个开源企业资源规划(ERP)系统。它提供了一套企业应用程序,…

navicat无法连接远程的mysql--Host ‘xx.xx.xx.xx‘ is not allowed to connect to this MySQL server“

之前在远程虚拟机上面部署了mysql,想在本地客户端使用navicat连接数据库,结果提示:host xxx is not allowed to connect to this mysql server解决 出现这个提示,是由于我们使用root用户登录时,没有给root用户设置能访问的机器,所以我们设置一下,就可以了。1:登录mysql…