P5180-[模板]支配树
正题
题目链接:https://www.luogu.com.cn/problem/P5180
题目大意
给出\(n\)个点的一张有向图,求每个点支配的点数量。
\(1\leq n\leq 2\times 10^5,1\leq m\leq 3\times 10^5\)
解题思路
首先定义半支配点\(semi_x\)表示对于点\(x\)寻找一个\(dfn\)序最小的点\(y\)满足存在一条\(y\)到\(x\)的路径去掉头尾之后所有点的\(dfn\)序都大于\(x\)的。
考虑怎么求每个点的半支配点,考虑两种情况对于一个能够直接到达\(x\)的点\(y\)
- \(dfn_y<dfn_x\):那么\(y\)可能是\(x\)的半支配点
- \(dfn_y>dfn_x\):那么设\(v\)表示\(y\)到\(dfs\)根节点的路径上的某个点\(u\)的\(dfn\)序最小的半支配点,那么\(v\)可能是\(u\)的半支配点
主要是第二种情况我们相当于要找一个在某个点到根节点路径上的点使得它的半支配点\(dfn\)序最小。
那么可以考虑倒序枚举,然后用带权并查集维护那个半支配点编号最小的。
之后就是半支配点有什么用,大概就是半支配点向点连边那么新的图支配关系不变。
所以一种暴力的做法就是直接跑\(DAG\)的支配树求法,但是有更快的。
考虑对于一个点\(x\)和它的半支配点\(y\),如果\(y\)到\(x\)的路径上我们找到一个半支配点\(dfn\)序最小的节点\(u\)且它的半支配点为\(v\)。
那么如果
- \(v=y\),那么证明整条路径上没有\(dfn\)序更小的半支配点,\(y\)就是\(x\)的支配点。
- \(d_u>d_y\),那么显然\(u\)有更小的支配点支配这套路径,所以\(u\)的支配点就是\(y\)的支配点
这个过程中\(u\)和\(v\)的维护和上面一样,所以可以一起求解。
但是我们可以暂时不知道\(u\)的支配点,所以可以先记录,最后在正序的记回去。
时间复杂度\(O(n\alpha(n))\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2100;
struct node{
int l,r;
}q[110000];
int n,m,k,t,ans,p[N],st[N][26],ss[N][26],nxt[N],f[N][N],pre[N][N];
char T[N],S[N];
bool cmp(node x,node y)
{return x.l<y.l;}
int main()
{
freopen("lcs.in","r",stdin);
freopen("lcs.out","w",stdout);
scanf("%s",T+1);m=strlen(T+1);
scanf("%s",S+1);n=strlen(S+1);
for(int i=1;i<=m;i++){
for(int j=0;j<26;j++)
st[i][j]=st[i-1][j]+(T[i]=='a'+j);
}
for(int i=1;i<=n;i++){
for(int j=0;j<26;j++)
ss[i][j]=ss[i-1][j]+(S[i]=='a'+j);
}
scanf("%d",&k);
for(int i=1;i<=k;i++)
scanf("%d%d",&q[i].l,&q[i].r),q[i].l++,q[i].r++;
sort(q+1,q+1+k,cmp);
int nowr=0,pr=0;
for(int i=1;i<=k;i++){
if(q[i].l>nowr){
nxt[pr]=nowr;
for(int j=nowr+1;j<q[i].l;j++)nxt[j]=j;
pr=q[i].l;nowr=q[i].r;
}
else nowr=max(q[i].r,nowr);
}
nxt[pr]=nowr;
for(int i=nowr+1;i<=n;i++)nxt[i]=i;
for(int i=1;i<=n;i++)
if(nxt[i])p[++t]=i;
for(int i=1;i<=m;i++)
for(int j=1;j<=t;j++){
int l=p[j],r=nxt[l],L=i;
for(int z=min(r-l,m-L);z>=0;z--){
bool flag=1;
for(int k=0;k<26;k++)
if(ss[r][k]-ss[l-1][k]<st[L+z][k]-st[L-1][k])
{flag=0;break;}
if(flag){pre[i][j]=z+1;break;}
}
}
for(int i=1;i<=m;i++)
for(int j=1;j<=t;j++){
int l=p[j],r=nxt[l],R=i;
if(pre[i][j]==r-l+1)continue;
for(int z=min(r-l,R-1)-1;z>=0;z--){
bool flag=1;
for(int k=0;k<26;k++)
if(ss[r][k]-ss[l-1][k]<st[R][k]-st[R-z-1][k])
{flag=0;break;}
if(flag){f[i+1][j+1]=z+1;ans=max(ans,z+1);break;}
}
}
for(int i=1;i<=m;i++)
for(int j=1;j<=t;j++){
int l=p[j],r=nxt[l];
if(pre[i][j]==r-l+1){
f[i+r-l+1][j+1]=max(f[i+r-l][j+1],f[i][j]+r-l+1);
ans=max(ans,f[i][j]+r-l+1);
}
ans=max(ans,f[i][j]+pre[i][j]);
}
printf("%d\n",ans);
return 0;
}
P5180-[模板]支配树的更多相关文章
- [HDU]4694 Important Sisters(支配树)
支配树模板 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ...
- P3384 【模板】树链剖分
P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...
- 洛谷P3368 【模板】树状数组 2
P3368 [模板]树状数组 2 102通过 206提交 题目提供者HansBug 标签 难度普及/提高- 提交 讨论 题解 最新讨论 暂时没有讨论 题目描述 如题,已知一个数列,你需要进行下面两 ...
- 洛谷P3374 【模板】树状数组 1
P3374 [模板]树状数组 1 140通过 232提交 题目提供者HansBug 标签 难度普及/提高- 提交 讨论 题解 最新讨论 题目描述有误 题目描述 如题,已知一个数列,你需要进行下面两 ...
- hdu 1754 I Hate It (模板线段树)
http://acm.hdu.edu.cn/showproblem.php?pid=1754 I Hate It Time Limit: 9000/3000 MS (Java/Others) M ...
- 康复计划#4 快速构造支配树的Lengauer-Tarjan算法
本篇口胡写给我自己这样的老是证错东西的口胡选手 以及那些想学支配树,又不想啃论文原文的人- 大概会讲的东西是求支配树时需要用到的一些性质,以及构造支配树的算法实现- 最后讲一下把只有路径压缩的并查集卡 ...
- luogu3384 【模板】树链剖分
P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...
- luogu2597-[ZJOI2012]灾难 && DAG支配树
Description P2597 [ZJOI2012]灾难 - 洛谷 | 计算机科学教育新生态 Solution 根据题意建图, 新建一个 \(S\) 点, 连向每个没有入边的点. 定义每个点 \( ...
- HDU.4694.Important Sisters(支配树)
HDU \(Description\) 给定一张简单有向图,起点为\(n\).对每个点求其支配点的编号和. \(n\leq 50000\). \(Solution\) 支配树. 还是有点小懵逼. 不管 ...
随机推荐
- spring security 入门级全篇代码
CustomAccessDecisionManager 类 ---------------------------------------------------------------------- ...
- 互斥锁(Lock)
转载至:https://www.cnblogs.com/dolphin0520/p/3923167.html 一.synchronized的缺陷 synchronized是java中的一个关键字,也就 ...
- 安全强化机制——SELinux
1.基本 SELINUX 安全性概念 SELINUX(Security Enhanced Linux),意思是安全增强型Linux, 是可保护你系统安全性的额外机制 在某种程度上 , 它可以被看作是与 ...
- Microsoft Remote Desktop 通过 .rdp 文件登录
最近在淘宝上买了「市场洞察」子账号,说是子账号,其实是需要登录到他们的 Windows 服务器上才能用的.并且子账号也是 5-6 个人共用的,且不说远程服务器很老又有延迟,经常是我想添加一个监控店铺或 ...
- 七、Abp vNext 基础篇丨文章聚合功能下
介绍 不好意思这篇文章应该早点更新的,这几天在忙CICD的东西没顾得上,等后面整好了CICD我也发2篇文章讲讲,咱们进入正题,这一章来补全剩下的 2个接口和将文章聚合进行完善. 开工 上一章大部分业务 ...
- 使用Keepalived实现Nginx的双机主备高可用
1.概述 前面我们聊过使用 Nginx 为 后端Tomcat 做负载均衡.高可用,但是这时Nginx又成了单点,如果Nginx不幸挂掉,整个网站便无法访问. 此时我们就会用到另一个软件 -- Keep ...
- 内核软中断之tasklet机制
1. 软中断IRQ简介 软中断(SoftIRQ)是内核提供的一种基于中断的延时机制, Linux内核定义的软中断有以下几种: enum { HI_SOFTIRQ=0, /*高优先级的tasklet*/ ...
- C语言实现任务调度与定时器
代码实现是在xl2tpd的源码中get到的,感觉很有意思的一段代码.基本功能就是实现定时器,时间到后从定时队列中取出,然后完成指定的任务. 1. schedule.c代码(自己添加了main函数,用来 ...
- 在C#中使用RSA进行加密和解密
这篇文章向您展示了如何在c#.net Windows窗体应用程序中使用RSA算法对字符串进行加密和解密.RSA是由Ron Rivest,Adi Shamir和Leonard Adleman开发的非对称 ...
- 【第八篇】- Git 查看提交历史之Spring Cloud直播商城 b2b2c电子商务技术总结
Git 查看提交历史 Git 提交历史一般常用两个命令: git log 在使用 Git 提交了若干更新之后,又或者克隆了某个项目,想回顾下提交历史,我们可以使用 git log 命令查看. 针对 ...