zoukankan      html  css  js  c++  java
  • 最小表示法总结

    问题解决

    一般用于解决一类最小表示或最小串的问题。

    问题引入

    例题:poj1509

    求它的循环串中字典序最小的串的开头。

    问题解决

    暴力

    找到所有的串存下来然后排序,复杂度(Theta(n^2))的。

    诡异做法

    建个后缀自动机然后遍历最小的字母边即可。

    正经一点的

    考虑两个指针(i),(j),一边扫过去的时候暴力求一下(i,j)(lcp)的长度,然后比一下(lcp)后一位,把大的那个指针往后移那么多位即可。

    代码实现

    /*
      mail: mleautomaton@foxmail.com
      author: MLEAutoMaton
      This Code is made by MLEAutoMaton
    */
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<iostream>
    using namespace std;
    #define ll long long
    #define REP(a,b,c) for(int a=b;a<=c;a++)
    #define re register
    #define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    inline int gi(){
    	int f=1,sum=0;char ch=getchar();
    	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    	return f*sum;
    }
    const int N=100010;
    char s[N];int n;
    int main(){
    	int T=gi();
    	while(T--){
    		scanf("%s",s);n=strlen(s);
    		int i=0,j=1;
    		while(i<n && j<n){
    			int k=0;
    			while(k<=n && s[(i+k)%n]==s[(j+k)%n])k++;
    			if(k>n)break;
    			if(s[(i+k)%n]<=s[(j+k)%n])j=j+k+1;
    			else i=i+k+1;
    			if(i==j)j=i+1;
    		}
    		printf("%d
    ",min(i+1,j+1));
    	}
    	return 0;
    }
    
  • 相关阅读:
    第三次作业
    第三次作业
    第二次作业
    作业
    日本人の名前の読み方
    免费学习网站小记
    The MySQL server is running with the --secure-file-priv option so it cannot execute
    转载:mysql 通过命令行方式导出查询结果时,如何带列名?
    转载-------------------HTML常用的特殊符号总结
    img 标签内如何在src中引用变量
  • 原文地址:https://www.cnblogs.com/fexuile/p/11625861.html
Copyright © 2011-2022 走看看