zoukankan      html  css  js  c++  java
  • AcWing 141 周期 (KMP)

    题目链接:https://www.acwing.com/problem/content/description/143/

    引理:(S[1~i]) 具有长度为 (len < i) 的循环元的充要条件是 (len) 能整除 (i), 并且
    (S[len+1~i] = S[1~i-len])

    还有个小性质:一个字符串的任意循环元的长度必然是最小循环元长度的倍数
    证明:
    如果存在循环元长度不是最小循环元长度的倍数,则肯定存在长度为较长循环元长度模最小循环元长度的循环元,
    此循环元比最小循环元小,矛盾

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 1000010;
    
    int n;
    int nxt[maxn];
    char s[maxn];
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
    	int Case = 0;
    	while(n = read()){
    		if(!n) break;
    		scanf("%s",s + 1);
    		printf("Test case #%d
    ",++Case);
    		
    		nxt[1] = 0;
    		for(int i=2, j=0;i<=n;++i){
    			while(j && s[i] != s[j+1]) j = nxt[j];
    			if(s[i] == s[j+1]) ++j;
    			nxt[i] = j;	
    		}
    		
    		for(int i=2;i<=n;++i){
    			int j = nxt[i];
    			if((i % (i - nxt[i])) == 0 && nxt[i] != 0) printf("%d %d
    ",i, i / (i - j));
    		}
    		printf("
    ");
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    UVa 1605
    UVa 120
    UVa 10384
    UVa 11694
    UVa 11846
    常用小函数
    【DP】:CF #319 (Div. 2) B. Modulo Sum
    类的无参方法
    类和对象
    七言
  • 原文地址:https://www.cnblogs.com/tuchen/p/13942990.html
Copyright © 2011-2022 走看看