【CF700E】Cool Slogans【后缀自动机】【可持久化线段树合并】【树上倍增】

传送门

题意:给定字符串SSS,求一堆字符串s1,s2,s3,...,sks_1,s_2,s_3,...,s_ks1,s2,s3,...,sk,满足s1s_1s1SSS的子串,且sis_isisi−1s_{i-1}si1中至少出现两次,最大化kkk

∣S∣≤200000|S| \leq 200000S200000

神仙题

显然建出后缀自动机然后在failfailfail树上乱搞

但很快发现不好描述出现两次

于是考虑回归到后缀自动机的本质:endposendposendpos

对于子串S,TS,TS,T,如果SSSTTT中出现两次

那么在某一个TTT的覆盖范围里,SSS出现了两次

换句话说,对于TTT的任意一个endposendposendpos,记为pos[T]pos[T]pos[T],其覆盖范围为[pos[T]−len[T],pos[T]][pos[T]-len[T],pos[T]][pos[T]len[T],pos[T]]

这段里出现了两个[pos[S]−len[S],pos[S]][pos[S]-len[S],pos[S]][pos[S]len[S],pos[S]]

[pos[T]−len[T]+len[S],pos[T]][pos[T]-len[T]+len[S],pos[T]][pos[T]len[T]+len[S],pos[T]]中有至少两个SSSendposendposendpos

于是可以用可持久化线段树来维护,由于某个点的endposendposendpos等于其failfailfail树的儿子的endposendposendpos的并集,写个线段树合并即可。

查询的时候由于是单调的,用倍增查最下面的满足条件的祖先。

复杂度O(nlog2n)O(nlog^2n)O(nlog2n)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#define MAXN 400005
using namespace std;
namespace SGT
{int ch[MAXN<<5][2],sum[MAXN<<5],cnt;inline int copy(const int& x){int ans=++cnt;ch[ans][0]=ch[x][0],ch[ans][1]=ch[x][1],sum[ans]=sum[x];return ans;}void insert(int& x,int l,int r,int k){++sum[x=++cnt];if (l==r) return;int mid=(l+r)>>1;if (k<=mid) insert(ch[x][0],l,mid,k);else insert(ch[x][1],mid+1,r,k);}int merge(int x,int y){if (!x||!y) return x|y;int p=copy(x);sum[p]+=sum[y];ch[p][0]=merge(ch[p][0],ch[y][0]);ch[p][1]=merge(ch[p][1],ch[y][1]);return p;}int getpos(int x,int l,int r){if (l==r) return l;int mid=(l+r)>>1;if (sum[ch[x][0]]) return getpos(ch[x][0],l,mid);else return getpos(ch[x][1],mid+1,r);}int query(int x,int l,int r,int ql,int qr){if (ql<=l&&r<=qr) return sum[x];if (r<ql||qr<l) return 0;int mid=(l+r)>>1;return query(ch[x][0],l,mid,ql,qr)+query(ch[x][1],mid+1,r,ql,qr);}	
}
int n;
char s[MAXN];
namespace SAM
{int ch[MAXN][26],fa[MAXN],len[MAXN],pos[MAXN],tot=1,las=1;int rt[MAXN];void insert(int c){int cur=++tot,p=las;len[cur]=len[p]+1;las=cur;for (;p&&!ch[p][c];p=fa[p]) ch[p][c]=cur;if (!p) return (void)(fa[cur]=1);int q=ch[p][c];if (len[q]==len[p]+1) fa[cur]=q;else{int _q=++tot;len[_q]=len[p]+1;fa[_q]=fa[q];fa[q]=fa[cur]=_q;memcpy(ch[_q],ch[q],sizeof(ch[q]));for(;ch[p][c]==q;p=fa[p]) ch[p][c]=_q;}}int jump[MAXN][20];int a[MAXN],c[MAXN],f[MAXN]={-1};inline bool check(int x,int y){return len[x]==0||SGT::query(rt[x],1,n,pos[y]-len[y]+len[x],pos[y])>=2;}int build(){for (int i=1;i<=n;i++) insert(s[i]-'a'),SGT::insert(rt[las],1,n,i);for (int i=1;i<=tot;i++) ++c[len[i]];for (int i=1;i<=n;i++) c[i]+=c[i-1];for (int i=tot;i>=1;i--) a[c[len[i]]--]=i;for (int i=tot;i>=1;i--){pos[a[i]]=SGT::getpos(rt[a[i]],1,n);rt[fa[a[i]]]=SGT::merge(rt[fa[a[i]]],rt[a[i]]);}for (int i=1;i<=tot;i++){jump[a[i]][0]=fa[a[i]];for (int k=1;k<20;k++) jump[a[i]][k]=jump[jump[a[i]][k-1]][k-1];int anc=a[i];for (int k=19;k>=0;k--) if (!check(jump[anc][k],a[i])) anc=jump[anc][k];anc=fa[anc];f[a[i]]=f[anc]+1;}int mx=0;for (int i=1;i<=tot;i++) mx=max(mx,f[i]);return mx;}	
}
int main()
{scanf("%d",&n);scanf("%s",s+1);printf("%d\n",SAM::build());return 0;
}

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

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

相关文章

P1377 [TJOI2011]树的序 笛卡尔树优化建树

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一棵二叉树的生成序列&#xff0c;让你输出一个字典序最小的序列&#xff0c;使其生成的二叉树与原来的二叉树相同。 思路&#xff1a; 首先想到暴力建树&#xff0c;让后输出先序遍历即可&#xff0c…

译 | .NET Core 基础架构进化之路(二)

原文&#xff1a;Matt Mitchell翻译&#xff1a;Edi Wang&#xff08;接上篇 译 | .NET Core 基础架构进化之路&#xff08;一&#xff09;&#xff09;Maestro 及依赖流.NET Core 3.0 基础结构难题的最后一部分就是我们所说的依赖项流。这不是 .NET Core 的唯一概念。除非它们…

【NOI2019】回家路线【无后效性dp状态设计】【斜率优化】

传送门 题意&#xff1a;给定MMM个班车&#xff0c;每个班车pip_ipi​时刻从xix_ixi​发车qiq_iqi​到达yiy_iyi​&#xff0c;等车ttt时间花费代价At2BtCAt^2BtCAt2BtC,在ttt时刻到达花费ttt的代价&#xff0c;求从111到NNN的最小花费。 1≤N≤100000,1≤M≤2000001 \leq N \…

Codeforces Round #628 (Div. 2) E. Ehab‘s REAL Number Theory Problem 巧妙的质因子建图

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你nnn个数&#xff0c;每个数的因子个数不超过777个&#xff0c;选出最少的数使其乘积为平方数。 n≤1e5n\le 1e5n≤1e5 思路&#xff1a; 由于因子不超过777个&#xff0c;所以由约数个数(1p1)∗(1p2)∗…

在.Net Core中实现一个WebSocket路由

Net Core中使用WebSocket默认是没有路由系统的&#xff0c;只能通过Request.Path"/xxx"来判断请求&#xff0c;例如&#xff1a;1 2 3 4 5 6 7 8 91011121314151617181920app.Use(async (context, next) >{ if (context.Request.Path "/ws") { …

【CF1189D】Add on a Tree【结论】【构造】

传送门 题意&#xff1a;给一棵NNN个结点的树&#xff0c;构造或判断无法构造若干次操作&#xff0c;每次操作选择两个叶节点将路径上的边加上一定整数权值&#xff0c;使得每条边等于给定权值。权值互不相同且为偶数。 1≤N≤10001 \leq N \leq10001≤N≤1000 结论&#xff…

Codeforces Round #628 (Div. 2) F. Ehab‘s Last Theorem dfs树

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你个nnn个点mmm条边的图&#xff0c;可以选择完成以下两个任务中的一个&#xff1a; (1)(1)(1)找出大小恰好为n\sqrt nn​的一个独立集。 (2)(2)(2)找出一个长度≥n\ge \sqrt n≥n​的一个环。 n≤1e5,m≤…

Dapper介绍--Micro-ORM

一&#xff0e;概述目前对于.net的数据访问ORM工具很多&#xff0c;EF和EF Core是一个重量级的框架。最近在搭建新的项目架构&#xff0c;来学习一下轻量级的数据访问ORM工具Dapper。Dapper支持SQL Server&#xff0c;MySQL&#xff0c;Sqlite&#xff0c;SqlCE&#xff0c;Fir…

剑指 Offer 31. 栈的压入、弹出序列

思路&#xff1a;模拟就完事 class Solution { public:bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {stack<int> c;int idx0;for(int v:pushed){c.push(v);while(c.size()&&c.top()popped[idx]){c.pop();idx;}…

【CF1189F】Array Beauty【dp】【复杂度玄学优化】

传送门 题意&#xff1a;给一个长度为NNN的序列aaa,从中选出kkk个&#xff0c;定义一个序列的美丽度为最接近的两个数的差的绝对值&#xff0c;求所有方案的美丽度之和模998244353998244353998244353。 N≤1000,ai≤100000N \leq 1000,a_i \leq100000N≤1000,ai​≤100000 显…

Educational Codeforces Round 84 (Rated for Div. 2) D. Infinite Path 构建环 + 思维

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 懒得写了&#xff0c;直接贴图了。 思路&#xff1a; 遇事不决画成图&#xff0c;考虑将iii向p[i]p[i]p[i]连一个边&#xff0c;可以发现每个点入度为111&#xff0c;出度为111&#xff0c;所以画出来是若…

WSL+VSCODE体验UBUNTU环境下的开发

首先安装 WSL&#xff0c;我这里选择的是 ubuntu18.04 这个应用。切换 WSL 的默认用户为 root 用户切换成 root 用户主要是避免后续开发中遇到权限问题比较麻烦&#xff0c;直接默认 root 解决问题。找到ubuntu安装目录&#xff0c;一般在C:\Program Files\WindowsApps\Canonic…

程序员修仙之路--优雅快速的统计千万级别uv

菜菜&#xff0c;咱们网站现在有多少PV和UV了&#xff1f;Y总&#xff0c;咱们没有统计pv和uv的系统&#xff0c;预估大约有一千万uv吧写一个统计uv和pv的系统吧网上有现成的&#xff0c;直接接入一个不行吗&#xff1f;别人的不太放心&#xff0c;毕竟自己写的&#xff0c;自己…

【CF1230E】Kamil and Making a Stream【GCD性质】【暴力vector】

传送门 题意:给一棵带点权的有根树&#xff0c;求所有满足uuu是vvv的祖先的路径(u,v)(u,v)(u,v)的路径上所有点权的gcdgcdgcd的和模1e971e971e97。 N≤100000N \leq 100000N≤100000 看到连续gcdgcdgcd多半是根据单调性维护链表之类的 对于每个点&#xff0c;记录所有祖先到…

P3391 【模板】文艺平衡树 fhq-treap 模板

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 这是学splaysplaysplay的时候的一个模板题&#xff0c;之前学过fhq−treapfhq-treapfhq−treap&#xff0c;但是没怎么用他做过题&#xff0c;今天一做还发现不少问题&#xff0c;真是眼高…

123. 买卖股票的最3佳时机 III

思路&#xff1a;动态规划&#xff0c; dp1是当前第一次买入的最大值 dp2是当前第一次卖出的最大值 dp3是当前第二次买入的最大值 dp4是当前第二次卖出的最大值 转移看代码&#xff1a; class Solution { public:int maxProfit(vector<int>& prices) {int dp1-…

Matrix Decompressing UVA - 11082 最大流 + 输出方案

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给出前iii行的元素和A[i]A[i]A[i]&#xff0c;前jjj列的元素B[j]B[j]B[j]&#xff0c;让你构造一个矩阵使得其满足前iii行的元素和是A[i]A[i]A[i]&#xff0c;前jjj列的元素和是B[j]B[j]B[j]。 r,c≤20r,c\l…

微软正式开源WSL 2的内核源码

微软在今年5月举办的 Build 2019 上宣布了第二代 Windows 的 Linux 子系统 —— WSL 2。与第一代相比&#xff0c;WSL 2 重新设计了架构&#xff0c;使用真正的 Linux 内核&#xff0c;支持在 Windows 上运行 ELF64 Linux 二进制文件。按照计划&#xff0c;WSL 2 的初始版本已于…

【NOI2016】优秀的拆分【后缀数组】【ST表】【关键点】【调和级数复杂度】【差分】

传送门 题意&#xff1a;如果一个字符串可以拆分为AABB的形式&#xff0c;其中A和B是任意非空字符串&#xff0c;则我们这种拆分是优秀的。求给定串的所有子串的拆分方案数之和。 N≤30000N \leq30000N≤30000 本来是个神仙题 但明明一个O(nlogn)O(nlogn)O(nlogn)的题为啥只…

剑指 Offer 43. 1~n 整数中 1 出现的次数(数位dp)

思路&#xff1a;就是数位dp&#xff0c;dp[idx][sum][limit]代表&#xff0c;到idx位&#xff0c;前面有sum个0&#xff0c;有没有limit限制&#xff1b; class Solution { public:int dp[20][50][2];int len; int pos[20];int countDigitOne(int n) {for(int i0;i<15;i)f…