• ABC240 Ex Sequence of Substrings


    考虑按 \(l\) 扫描线,每次向右扩展 \(r\).

    考虑记录 \(f_i\) 为答案为 \(i\) 的字典序最小的 \([l,r]\)

    考虑到在 \(l,r\) 上还有一维偏序,所以只有在 \(l\) 扫到答案的 \(r\) 时再加入答案。

    考虑到最长的长度不超过 \(\sqrt n\),可以二分找到 \(LCP\),那么复杂度为 \(O(n\sqrt n log)\)

    点击查看代码
    //晦暗的宇宙,我们找不到光,看不见尽头,但我们永远都不会被黑色打倒。——Quinn葵因
    #include<bits/stdc++.h>
    #define ll long long
    #define N 30000
    #define M 400
    
    unsigned ll key[M];
    
    unsigned ll H[N][M];
    
    int n;
    int lim;
    
    char s[N];
    
    int li[N],ri[N];
    
    using std::vector;
    
    using std::pair;
    
    #define pii pair<int,int>
    
    int ans = 0;
    
    #define mp std::make_pair
    
    vector<pii>R[N];
    
    #define mid  ((L + R) >> 1)
    
    inline int cmp(int l,int r,int x,int y){//cmp [l,r] [x,y] 1 : > 0 : = -1 : <
    //	std::cout<<"CHECK"<<"("<<l<<","<<r<<") "<<"("<<x<<","<<y<<")"<<"\n";
    	if(x == 0)return 1;if(x == n + 1)return -1;
    	int L = 0,R = std::min(r - l + 1,y - x + 1),res = 0;
    	while(L <= R){
    		if(H[l][mid] == H[x][mid])
    		res = mid,L = mid + 1;
    		else
    		R = mid - 1;
    	}
    //	std::cout<<"LCP "<<res<<"\n";
    	if(res != std::min(r - l + 1,y - x + 1)){
    		if(s[l + res] < s[x + res])return -1;else return 1;
    	}else{
    		int len1 = r - l + 1,len2 = y - x + 1;
    		if(len1 == len2)return 0;
    		if(len1 < len2)return -1;
    		if(len1 > len2)return 1;
    	}
    }
    
    int main(){
    	srand(time(0));
    	scanf("%d",&n);
    	lim = sqrt(2 * n);
    	for(int i = 1;i <= lim;++i)
    	key[i] = rand();
    	scanf("%s",s + 1);
    	for(int i = 1;i <= n;++i)
    	for(int j = 1;j <= lim;++j){
    		H[i][j] = H[i][j - 1] + key[j] * s[i + j - 1];
    //		std::cout<<i<<" "<<j<<" "<<H[i][j]<<"\n";
    	}
    	for(int i = 1;i <= n;++i)
    	li[i] = ri[i] = n + 1;
    	for(int i = 1;i <= n;++i){
    		int k = 0;
    		for(int j = 1;j <= M && i + j - 1 <= n;++j){
    			int l = i,r = i + j - 1;
    			while(k <= n && cmp(l,r,li[k],ri[k]) == 1)++k;
    //			std::cout<<i<<" "<<j<<" "<<k<<"\n";
    			ans = std::max(ans,k);
    			R[r].push_back(mp(l,k));
    		}
    		for(auto U : R[i]){
    			int l = U.first;
    			int k = U.second;
    			int r = i;
    			if(cmp(l,r,li[k],ri[k]) == -1)li[k] = l,ri[k] = r;/*,std::cout<<"F_"<<k<<"->"<<"("<<l<<","<<r<<")"<<"\n";*/
    		}
    	}
    	std::cout<<ans<<"\n";
    }
    
  • 相关阅读:
    SpringMVC(十六) 处理模型数据之SessionAttributes
    SpringBoot_web开发-【实验】-登陆&拦截器
    SpringBoot_web开发-【实验】-国际化
    SpringBoot_web开发-【实验】-引入资源
    什么是NIO?
    SpringBoot_web开发-扩展与全面接管SpringMVC
    SpringBoot_web开发-webjars&静态资源映射规则
    SpringBoot_web开发-thymeleaf语法
    SpringBoot_web开发-引入thymeleaf
    (实例)Linux 内核添加exfat驱动
  • 原文地址:https://www.cnblogs.com/dixiao/p/16112920.html
Copyright © 2020-2023  润新知