模板:P6114 【模板】Lyndon 分解Runs(字符串)

你不会连跑步都不会吧。

(逃

前言

SAM:runs?那我run了

比 SAM 看起来层次更高的奥妙算法。
理论证明比较复杂,但板子写起来都比较简单。
本文会略过很多的证明。

Lyndon 分解

Definition
如果一个串本身比它的所有真后缀字典序都小,我们就称这样的一个串为 Lyndon 串
如果一个字符串的划分 w1w2...wkw_1w_2...w_kw1w2...wk 满足所有的 w 都是 Lyndon 串,且满足字典序 w1≥w2≥...≥wkw_1\ge w_2\ge ...\ge w_kw1w2...wk,则成其为字符串的 Lyndon 分解

可以证明,任意字符串的 Lyndon 分解是唯一的。

求解

如何求呢?
设考虑到第 i 位。
此时未确定的分解必然形如 www...w′www...w'www...ww′w'wwww 的一个前缀。
如果新字符和循环节对应位置相同,不做处理。
如果新字符更大,合并成一整块。
如果新字符更小,把前面的若干个循环节分裂出来,然后回退到 w′w'w,继续处理。
时间复杂度 O(n)O(n)O(n)

int i=1,j=2,l=1,res(0);
for(;i<=n;j++){if(s[j]>s[j-l]) l=j-i+1;else if(s[j]<s[j-l]){while(i+l<=j){res^=(i+l-1);i+=l;		}j=i;l=1;}  
}

Runs

definition:
如果一个字符串的某个字串可以写成 ppp...p′ppp...p'ppp...p 的形式,且其是符合条件的极长子串,则称其为一个 runs。(周期p至少出现两次)
对于每一个runs,其长度恰好为p的lyndon串称为其的 lyndon根

每个runs有且只有一个本质不同的lyndon根。

Lemma:设 ltilt_iltimax⁡j,s(i,j)为lyndon串\max j,s(i,j)为lyndon串maxj,s(i,j)lyndon,那么对于一个 lyndon 根(i,j),在 <0,<1<_0,<_1<0,<1 两种相反的比较符定义下,至少有一种情况满足 lti=jlt_i=jlti=j

所以我们可以求出 ltltlt 数组,然后通过 (i,lti)(i,lt_i)(i,lti) 反推出其对应的runs(通过求lcp和lcs容易求出)。

那么如何求出 ltltlt 呢?
lyndon 分解还有一种单调栈的求法,当栈顶字典序小于当前元素时不断把栈顶块和当前块合并。不难发现此时得到的块的右端点就是对应的 ltilt_ilti

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned ll
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")inline ll read() {ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
const int N=1e6+100;
const int mod=1e9+7;
const int inf=1e9+100;
const double eps=1e-9;bool mem1;bool Flag=0;inline ll ksm(ll x,ll k,int mod){ll res(1);x%=mod;while(k){if(k&1) res=res*x%mod;x=x*x%mod;k>>=1;}return res;
}int n,m;
char s[N];
const int bas=31;
ull h[N],mi[N];
void init(){mi[0]=1;for(int i=1;i<=n;i++){mi[i]=mi[i-1]*bas;h[i]=h[i-1]*bas+s[i]-'a'+1;}return;
}
inline ll Hash(int l,int r){return h[r]-mi[r-l+1]*h[l-1];
}
inline int lcp(int i,int j){int st=0,ed=n-max(i,j)+1;while(st<ed){int mid=(st+ed+1)>>1;if(Hash(i,i+mid-1)==Hash(j,j+mid-1)) st=mid;else ed=mid-1;}return st;
}
inline int lcs(int i,int j){int st=0,ed=min(i,j);while(st<ed){int mid=(st+ed+1)>>1;if(Hash(i-mid+1,i)==Hash(j-mid+1,j)) st=mid;else ed=mid-1;}return st;
}
map<int,int>mp[N];
struct run{int l,r,p;bool operator < (const run &oth)const{if(l!=oth.l) return l<oth.l;else return r<oth.r;}
};
vector<run> ans;
inline void ins(int i,int j){if(j==n) return;j++;int p=(j-i),pre=i-lcs(i,j)+1,suf=j+lcp(i,j)-1;//printf("ins: (%d %d) (%d %d)\n",i,j,pre,suf);if(mp[pre][suf]) return;if(suf-pre+1>=2*p){mp[pre][suf]=1;ans.emplace_back((run){pre,suf,p});}return;
}
int cmp(int i,int j,int x,int y){//i<j?int len=lcp(i,j);//printf("i=%d j=%d x=%d y=%d len=%d\n",i,j,x,y,len);if(len>=min(x,y)){if(x<y) return 1;else if(x==y) return 0;else return -1;}else{if(s[i+len]<s[j+len]) return 1;else if(s[i+len]==s[j+len]) return 0;else return -1;}
}
int zhan[N],top;//zhan:right pos
void work(){top=0;for(int i=n;i>=1;i--){int pos=i;while(top&&cmp(i,pos+1,pos-i+1,zhan[top]-pos)==1) pos=zhan[top--];//if(top) printf("  f=%d\n",cmp(i,pos+1,pos-i+1,zhan[top]-pos));zhan[++top]=pos;//printf("i=%d pos=%d\n",i,pos);ins(i,pos);}  
}bool mem2;
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifscanf("%s",s+1);n=strlen(s+1);init();work();for(int i=1;i<=n;i++) s[i]='a'-s[i]+1;work();sort(ans.begin(),ans.end());printf("%d\n",(int)ans.size());for(run o:ans) printf("%d %d %d\n",o.l,o.r,o.p);return 0;
}
/*
*/

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

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

相关文章

ASP.NET Core 3.0预览版体验

目前.NET Core 3.0的版本为.NET Core 3.0 Preview 3&#xff0c;对应ASP.NET Core 3.0 Preview 3。ASP.NET Core 3.0 之后将不再支持.NET Framework&#xff0c;只运行在.NET Core 上面。ASP.NET Core 3.0 现在已经出到了第三个预览版&#xff0c;增加和改进了很多功能。环境准…

【无码专区13】最小公倍数(线段树)

因为只有std&#xff0c;没有自我实现&#xff0c;所以是无码专区 主要是为了训练思维能力 my idea顾名思义&#xff0c;记录了我的整个思维过程&#xff0c;以及自己部分实现细节口胡&#xff0c;还有期望分数 solution才是dls正解&#xff0c;但是因为只有潦草几句&#x…

2021牛客暑期多校训练营2

2021牛客暑期多校训练营2 题号题目知识点AArithmetic ProgressionBCannonCDraw GridsDEr Ba GameEGas StationFGirlfriendGLeague of LegendsHOlefinIPenguinsbfsJProduct of GCDsKStackLWeChat Walk

P6772 [NOI2020] 美食家(矩阵快速幂)

前言 无能狂怒。 见过甚至写过博客的trick&#xff0c;但就是想不起来了。 解析 做法1 设 ft,xf_{t,x}ft,x​ 表示 t 时刻在 x 的最大价值。 直接转移即可&#xff0c;时间复杂度 O(T(nm))O(T(nm))O(T(nm))&#xff0c;期望得分 40 分。 结合无脑转圈的 A 性质&#xff0c;…

C# .net 中 Timeout 的处理及遇到的问题

C# 中 Timeout 的处理前言最近在项目中要实现一个功能&#xff0c;是关于 Timeout 的&#xff0c;主要是要在要在 TCP 连接建立的时间 和 整个请求完成的时间&#xff0c;在这两个时间层面上&#xff0c;如果超出了设置的时间&#xff0c;就抛出异常&#xff0c;程序中断。研究…

[CodeJam 2019 Round 3] Rancake Pyramid(笛卡尔树)

CodeJam 2019 Round 3 Rancake Pyramidproblemsolutioncodeproblem 神奈子是个很爱打麻将的老婆婆&#xff0c;有一天她把她的麻将放成了 nnn 堆&#xff0c;第 iii 堆的高度为 aia_iai​ 。 因为她很喜欢风&#xff0c;所以她用风吹倒了最左边的 LLL 堆麻将和最右边的 RRR 堆…

Harbour.Space Scholarship Contest 2021-2022 (open for everyone, rated, Div. 1 + Div. 2)

Harbour.Space Scholarship Contest 2021-2022 (open for everyone, rated, Div. 1 Div. 2) 题号题目知识点ADigits Sum签到BReverse String思维CPenalty思维DBackspace逆向思维EPermutation Shift置换群FPairwise ModuloGCommon Divisor GraphHXOR and DistanceIStairs cf15…

模板:全局平衡二叉树

所谓全局平衡二叉树&#xff0c;就是在全局来看都很平衡的二叉树。 &#xff08;逃 前言 这个引言倒是实话&#xff08;雾 可以把一些本来只能用树剖两个 log 做的问题在单log 时间复杂度解决。 修改通常来说只能支持单点修改。 查询解决链上问题或者全局问题更为方便&#x…

[CodeJam 2021 Round 3] Square Free(调整法 / 字典序最小解网络流)

CodeJam 2021 Round3 Square Freeproblemsolutioncodecode-stdproblem 神奈子是个很爱打麻将的老婆婆&#xff0c;有一天她把她的麻将放进了一个 nmn\times mnm 的网格图里&#xff0c;每个麻将可以左斜着放入网格中&#xff08;如 / &#xff09;&#xff0c;也可以右斜着&am…

P6773 [NOI2020] 命运(dp、线段树合并)

前言 一道看起来很毒瘤但其实还算小清新的题&#xff1f; 理解后感觉其实并没有那么难。 暴力分非常足&#xff0c;好评。 奇妙的线段树合并技巧增加了。 解析 解法1 你是怎么手玩的样例一&#xff1f; 大部分&#xff08;比如我&#xff09;都是容斥吧。 把手玩的方法搬到…

ConsurrentDictionary并发字典知多少?

在上一篇文章你真的了解字典吗?一文中我介绍了Hash Function和字典的工作的基本原理.有网友在文章底部评论,说我的Remove和Add方法没有考虑线程安全问题.https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?redirectedfromMSDN&viewn…

[luogu 4292][bzoj 1758][WC2010] 重建计划(点分治 + dp + 单调队列优化 + 启发式合并)

[WC2010]重建计划problemsolutioncodeproblem 洛谷指路 solution 一看那个道路平均价值的式子&#xff1a;AvgValue∑e∈Sv(e)∣S∣\text{AvgValue}\frac{\sum_{e\in S}v(e)}{|S|}AvgValue∣S∣∑e∈S​v(e)​ 就是 0/1分数规划 的样子。 所以考虑二分最终的答案 midmidmid…

cf1553C. Penalty

cf1553C. Penalty 题意&#xff1a; 有十轮点球&#xff0c;两个队伍轮流进行&#xff0c;1表示进&#xff0c;0表示不进&#xff0c;&#xff1f;表示未知&#xff0c;如果比赛没有了悬念将直接结束。现在让你预测一个情况&#xff0c;使得进行的轮数最少。裁判在决定停止点…

ASP.NET Core 基于JWT的认证(二)

上一节我们对 Jwt 的一些基础知识进行了一个简单的介绍&#xff0c;这一节我们将详细的讲解,本次我们将详细的介绍一下 Jwt在 .Net Core 上的实际运用。.Net Core 2.2Visual Studio 2017ASP.NET Core WebAPI2在上一篇文章中&#xff0c;我们详细的介绍了JWT的知识&#xff0c;这…

P6774 [NOI2020] 时代的眼泪(分块)

前言 看到题目名&#xff1a;别骂了别骂了。 一道很中规中矩的YNOI吧。 卡在整块对整块的贡献上了。 这也确实算是本题最不好做的部分了。 前置知识&#xff1a;Yuno loves sqrt technology I 解析 区间逆序对加强版&#xff1f;很难不想到两道 YLST。 然而多了两维限制&a…

[NOIP2021] 数列(计数dp)

solution f[i][j][k][num][p]:2pf[i][j][k][num][p]:2^pf[i][j][k][num][p]:2p 选择了 iii 个&#xff0c;前 p−1p-1p−1 位 (202p−1)(2^0~2^{p-1})(20 2p−1) 已经选了jjj个&#xff0c;低位向高位进位上来 kkk&#xff0c;前 ppp 位已经确定有 numnumnum 个位置为 111&…

Xor sum HDU - 6955

Xor sum HDU - 6955 题意&#xff1a; 给定一个长度为n的整数序列&#xff0c;求其XOR和不小于k的最短连续子序列。 如果有多个相同长度的连续子序列&#xff0c;则打印具有最小左端点的连续子序列。 如果没有连续的子序列开关XOR总和不小于k&#xff0c;只需打印“-1”。 …

模板:子序列自动机(字符串)

所谓子序列自动机&#xff0c;就是根据子序列建立的自动机。 &#xff08;逃&#xff09; 前言 小清新算法。 解析 和其他自动机类似的&#xff0c;我们希望子序列自动机能且只能接受原串的所有子序列。 考虑一个问题&#xff1a;给你一个串 T&#xff0c;如何判断它是否是…

Docker最全教程之Go实战,墙裂推荐(十九)

前言与其他语言相比&#xff0c;Go非常值得推荐和学习&#xff0c;真香&#xff01;为什么&#xff1f;主要是可以直接编译成机器代码&#xff08;性能优越&#xff0c;体积非常小&#xff0c;可达10来M&#xff0c;见实践教程图片&#xff09;而且设计良好&#xff0c;上手门槛…

[BZOJ3093][Fdu校赛2012] A Famous Game(不等概率)

problem BOZJ3093 solution 逆概率公式&#xff0c;即贝叶斯(Bayes)公式&#xff1a; 假设 B1,B2,...,BnB_1,B_2,...,B_nB1​,B2​,...,Bn​ 是 Ω\OmegaΩ 的一个分割&#xff0c;P(A)>0P(A)>0P(A)>0&#xff0c;则有 P(Bk∣A)P(ABk)P(A)P(Bk)P(A∣Bk)∑i1nP(Bi)…