• 【LOJ】#3103. 「JSOI2019」节日庆典


    LOJ#3103. 「JSOI2019」节日庆典

    能当最小位置的值一定是一个最小后缀,而有用的最小后缀不超过(log n)

    为什么不超过(log n)个,看了一下zsy的博客。。

    假如(i = AAB)(j = AB)(B)(A)的一个严格前缀,(|j| < |i| < 2|j|)

    但是有(k = B),导致了若(j)(i)优,则(k)会比(j)优,(j)(k)优,则(i)会比(j)优,那么(j)就没用了

    然后取这(log)里最大的就是一段后缀和开头比较,可以预处理出每个串和开头的lcp,用扩展kmp

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define eps 1e-10
    #define ba 47
    #define MAXN 5005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 +c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    char s[3000006];
    int L,lcp[3000006];
    bool cmp(int l0,int r0,int l1,int r1) {
        if(r0 < l0) return true;
        if(r1 < l1) return false;
        int l = min(lcp[l0],min(r1,r0 - l0 + 1));
        if(s[l0 + l] <= s[l1 + l]) return true;
        return false;
    }
    void Solve() {
        scanf("%s",s + 1);
        L = strlen(s + 1);
        lcp[1] = L;int p = 0,r = 0;
        for(int i = 2 ; i <= L ; ++i) {
    	int t = 0;
    	if(r >= i) t = min(r - i + 1,lcp[i - p + 1]);
    	while(i + t <= L && s[t + 1] == s[i + t]) ++t;
    	lcp[i] = t;
    	if(r < i + t - 1) {p = i;r = i + t - 1;}
        }
        vector<int> f;f.clear();
        for(int i = 1 ; i <= L ; ++i) {
    	vector<int> g;g.clear();g.pb(i);
    	for(auto t : f) {
    	    while(g.size() && s[t + i - g.back()] < s[i]) g.pop_back();
    	    if(g.size() == 0 || s[t + i - g.back()] == s[i]) {
    		while(g.size() && i - t + 1 <= 2 * (i - g.back() + 1)) g.pop_back();
    		g.pb(t);
    	    }
    	}
    	f = g;
    	int res = f[0];
    	for(int j = 1 ; j < f.size() ; ++j) {
    	    if(cmp(f[j] + i - res + 1,res - 1,1,res - f[j] - 1)) res = f[j];
    	}
    	out(res);space;
        }
        enter;
    }
    int main(){
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    
  • 相关阅读:
    关于架构,关于系统,关于合作,我也得问问我们自己
    vs2013 无法打开 源 文件 "SDKDDKVer.h"
    视频基础知识汇总
    python gRPC接口调用
    python多线程同时执行2个函数任务之threading
    git基本操作_快速查询
    pycharm激活码 我是搬运工
    CodeReview的一些原则
    python多线程执行同一个函数任务之threading、ThreadPoolExecutor.map
    python程序超时处理 timeout_decorator
  • 原文地址:https://www.cnblogs.com/ivorysi/p/11011869.html
Copyright © 2020-2023  润新知