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\) 支配树. 还是有点小懵逼. 不管 ...
随机推荐
- windows上解决git每次重复输入账号密码
win7电脑: 1.在 C:\Users\Administrator 下 编辑 .gitconfig文件 2.在原有内容下添加一行(此行作用为自动保存,保存修改后再使用一次GIT,输入账号密码后下次即 ...
- C# 利用反射进行深拷贝
- QT 自定义控件 以及信号和槽的使用
自定义login 控件 Login头文件 #ifndef LOGIN_H #define LOGIN_H #include <QWidget> namespace Ui { class L ...
- Spring @Order注解的使用
注解@Order或者接口Ordered的作用是定义Spring IOC容器中Bean的执行顺序的优先级,而不是定义Bean的加载顺序,Bean的加载顺序不受@Order或Ordered接口的影响: 1 ...
- MySql 改变table的列名以及列的类型
1 ALTER TABLE table_name CHANGE COLUMN old_col_name new_col_name datatype; #改变table的列名以及列的类型
- ScheduledExecutorService中scheduleAtFixedRate方法与scheduleWithFixedDelay方法的区别
ScheduledExecutorService中scheduleAtFixedRate方法与scheduleWithFixedDelay方法的区别 ScheduledThreadPoolExecut ...
- Go版本依赖--伪版本
目录 1.简介 2. 什么是伪版本 3. 伪版本风格 4. 如何获取伪版本 1.简介 在go.mod中通常使用语义化版本来标记依赖,比如v1.2.3.v0.1.5等.因为go.mod文件通常是go命令 ...
- APP 兼容性测试之云测平台体验
前言 兼容性测试主要通过人工或自动化的方式,在需要覆盖的终端设备上进行功能用例执行,查看软件性能.稳定性等是否正常. 对于需要覆盖的终端设备,大型互联网公司,像BAT,基本都有自己的测试实验室,拥有大 ...
- MySQL基础2——常用命令
注意:MySQL在centos中安装的是5.7版本的,编辑MySQL时会有个报错,需要执行: set @@global.sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN ...
- 为 Memcached 构建基于 Go 的 Operator 示例
Operator SDK 中的 Go 编程语言支持可以利用 Operator SDK 中的 Go 编程语言支持,为 Memcached 构 建基于 Go 的 Operator 示例.分布式键值存储并管 ...