首页 > 其他 > 详细

Lyndon分解

时间:2021-04-24 20:55:43      阅读:29      评论:0      收藏:0      [点我收藏+]

Lyndon分解

这篇博客讲的十分详细,下面对在看博客时卡壳的地方和代码(实现非常精妙)进行解释。

  • 在博客中分三种情况讨论第二种的分解并非有固定下来,也就是说,t变长了。
  • 在博客中分三种情况讨论第二种合并原因是因为后面的由于\(s[k]\)变大了。
  • 博客中[:l]指的是结尾为l的前缀,[l:]指的是开头是l的后缀。
  • 在博客中分三种情况讨论第三种把t分解固定下来,是固定了h个Lyndon串,而非把所有\(t^h\)合并成一个串固定下来。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<deque>
#include<cstdlib>
#include<ctime>
#define dd double
#define ld long double
#define ll long long
#define ull unsigned long long
#define N 5000010
#define M number
using namespace std;

const int INF=0x3f3f3f3f;

inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
	while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
	return x*f;
}

char s[N];
int ans;

int main(){
    scanf("%s",s+1);
    int len=strlen(s+1);
    for(int i=1;i<=len;){
        int j=i,k=i+1;
        while(k<=len&&s[j]<=s[k]){
            if(s[j]<s[k]) j=i;
            else j++;
            k++;
        }
        while(i<=j){
            ans^=i+k-j-1;
            i+=k-j;
        }
    }
    printf("%d\n",ans);
    return 0;
}

可以知道,代码中只用了三个指针就完成了对Lyndon的分解。

  • 如果\(s[j]<s[k]\)那么就让t变长。
  • \(s[j]>s[k]\),我们统计答案。注意“-1”,\(i\)的位置是该串的第一个位置。

Lyndon分解

原文:https://www.cnblogs.com/TianMeng-hyl/p/14697364.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!