zoukankan      html  css  js  c++  java
  • HDU 6761 Minimum Index (字符串--Lyndon分解)

    题目:传送门

    题意

    给你一个字符串,求每个前缀的最小后缀对应的起始位置。

    总的字符串长度 <= 2e7

    思路

    Lydon 分解: 参考博客

    Lyndon 串:对于字符串x,如果x的字典序严格小于x的所有后缀的字典序,我们称x是简单串,或者Lyndon串。

    近似Lyndon串: 若x为Lyndon串,则xxxx为近似Lyndon串,x′为x的前缀。

    Lyndon分解: 将一个串x分作x1x2..xk,每一个部分都是Lyndon串,且 xi >= xi+1

    定理:

    Lyndon串是循环同构中字典序最小的一个。
    Lyndon分解唯一。
    两个Lyndon串a,ba<b,有abLyndon串。

    通过 Lyndon 分解 解此题: 参考博客

    #include <bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    #define UI unsigned int
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF 0x3f3f3f3f
    #define inf LLONG_MAX
    #define PI acos(-1)
    #define fir first
    #define sec second
    #define lb(x) ((x) & (-(x)))
    #define dbg(x) cout<<#x<<" = "<<x<<endl;
    using namespace std;
    
    const int N = 1e6 + 5;
    
    const LL mod = 1e9 + 7;
    
    int n;
    
    char a[N];
    
    LL ans[N];
    
    void solve() {
    
        scanf("%s", a);
    
        n = strlen(a);
    
        int i = 0, j, k;
    
        ans[0] = 1LL;
    
        while(i < n) {
    
            j = i + 1, k = i;
    
            while(j < n && a[k] <= a[j]) {
    
                if(a[k] == a[j]) {
    
                    ans[j] = j + ans[k] - k;
    
                    k++;
    
                }
    
                else {
    
                    k = i; ans[j] = i + 1;
    
                }
    
                j++;
    
            }
    
            while(i <= k) {
    
                i += j - k;
    
            }
    
            if(i == j && i < n) ans[j] = i + 1;
    
        }
    
        LL res = 0LL;
    
        dep(i, 0, n - 1) {
    
            res = (res * 1112LL % mod + ans[i]) % mod;
    
        }
    
        printf("%lld
    ", res);
    
    }
    
    
    int main() {
    
        int _; scanf("%d", &_);
        while(_--) solve();
    
    //    solve();
    
        return 0;
    }

     

  • 相关阅读:
    struts2学习笔记之校验器
    struts2学习笔记之文件上传
    在ASP.net MVC里用Jquery的Ajax功能调用相关LinqtoSQL生成的类出现错误循环引用
    Linq,企业类库,EXECL生成,Execl chart的一些基本操作记录.(一)
    记录Linq所学.
    记录一个很平常的想法.
    链表反序(C#版)
    oracle 体系结构
    Oracle的sys和system用户的区别
    数据库触发器的理解
  • 原文地址:https://www.cnblogs.com/Willems/p/13582123.html
Copyright © 2011-2022 走看看