正题

题目链接: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\)

  1. \(dfn_y<dfn_x\):那么\(y\)可能是\(x\)的半支配点
  2. \(dfn_y>dfn_x\):那么设\(v\)表示\(y\)到\(dfs\)根节点的路径上的某个点\(u\)的\(dfn\)序最小的半支配点,那么\(v\)可能是\(u\)的半支配点

主要是第二种情况我们相当于要找一个在某个点到根节点路径上的点使得它的半支配点\(dfn\)序最小。

那么可以考虑倒序枚举,然后用带权并查集维护那个半支配点编号最小的。

之后就是半支配点有什么用,大概就是半支配点向点连边那么新的图支配关系不变。

所以一种暴力的做法就是直接跑\(DAG\)的支配树求法,但是有更快的。

考虑对于一个点\(x\)和它的半支配点\(y\),如果\(y\)到\(x\)的路径上我们找到一个半支配点\(dfn\)序最小的节点\(u\)且它的半支配点为\(v\)。

那么如果

  1. \(v=y\),那么证明整条路径上没有\(dfn\)序更小的半支配点,\(y\)就是\(x\)的支配点。
  2. \(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-[模板]支配树的更多相关文章

  1. [HDU]4694 Important Sisters(支配树)

    支配树模板 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ...

  2. P3384 【模板】树链剖分

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  3. 洛谷P3368 【模板】树状数组 2

    P3368 [模板]树状数组 2 102通过 206提交 题目提供者HansBug 标签 难度普及/提高- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 如题,已知一个数列,你需要进行下面两 ...

  4. 洛谷P3374 【模板】树状数组 1

    P3374 [模板]树状数组 1 140通过 232提交 题目提供者HansBug 标签 难度普及/提高- 提交  讨论  题解 最新讨论 题目描述有误 题目描述 如题,已知一个数列,你需要进行下面两 ...

  5. 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 ...

  6. 康复计划#4 快速构造支配树的Lengauer-Tarjan算法

    本篇口胡写给我自己这样的老是证错东西的口胡选手 以及那些想学支配树,又不想啃论文原文的人- 大概会讲的东西是求支配树时需要用到的一些性质,以及构造支配树的算法实现- 最后讲一下把只有路径压缩的并查集卡 ...

  7. luogu3384 【模板】树链剖分

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  8. luogu2597-[ZJOI2012]灾难 && DAG支配树

    Description P2597 [ZJOI2012]灾难 - 洛谷 | 计算机科学教育新生态 Solution 根据题意建图, 新建一个 \(S\) 点, 连向每个没有入边的点. 定义每个点 \( ...

  9. HDU.4694.Important Sisters(支配树)

    HDU \(Description\) 给定一张简单有向图,起点为\(n\).对每个点求其支配点的编号和. \(n\leq 50000\). \(Solution\) 支配树. 还是有点小懵逼. 不管 ...

随机推荐

  1. redis和memecache有什么区别?

    1.memcache所有值均是简单地字符串,redis有复杂的数据类型. 2.memcache不支持数据持久化,redis支持数据持久化. 3.redis速度比memcache快,redis构建了自己 ...

  2. 干货!4大实验项目,深度解析Tag在可观测性领域的最佳实践!

    Opentelemetry协议,是CNCF(Cloud Native Computing Foundation-云原生计算基金会)定义的最新一代的可观测规范(目前还在孵化中),该规范定义了可观测性的三 ...

  3. 使用dom4j工具:获取xml中的标签属性(三)

    package dom4j_read; import java.io.File; import java.util.List; import org.dom4j.Attribute; import o ...

  4. SprngCloud微服务框架搭建(一)

    参照来源 :https://blog.csdn.net/forezp/article/details/70148833 1.简介 目前来说,SpringCloud是比较完整的微服务解决方案框架.不像其 ...

  5. Ubuntu 16.04LTS修改开机启动项

    装上Ubuntu16.04后,每次开机都得手选开机项,挺麻烦 sudo vi /etc/default/grub GRUB_DEFAULT=0GRUB_HIDDEN_TIMEOUT=0GRUB_HID ...

  6. Dubbo | Dubbo快速上手笔记 - 环境与配置

    目录 前言 1. Dubbo相关概念 1.1 自动服务发现工作原理 2. 启动文件 2.1 zookeeper-3.4.11\bin\zkServer.cmd 2.2 zookeeper-3.4.11 ...

  7. GUI常用监听事件

    概念 对鼠标.键盘等一系列事件做出相应的反馈 事件监听 //创建监听事件 public class Demo { public static void main(String[] args) { Fr ...

  8. vue 引用高德地图

    vue 引用地图之傻瓜式教程(复制粘贴即可用) npm 下载 npm install vue-amap --save main.js 代码 import AMap from 'vue-amap'; V ...

  9. 华为分析X HUAWEI Ads,上线深度转化事件回传功能,让ROI 看得见!

    华为分析X HUAWEI Ads,上线深度转化事件回传功能,让ROI 看得见! 随着移动应用生态的流量成本攀升.行业竞争加剧,越来越多的广告商希望通过精准投放来获取更高质量的深度转化用户,比如二手车. ...

  10. idea字节码插件JClassLib——阅读JVM字节码

    idea字节码插件JClassLib--阅读JVM字节码 生成字节码文件并查看 查看字节码文件的方式:javac 文件名.java 即可生成.class文件,但是这种方式不方便 java:是运行字节码 ...