51Nod 1554 欧姆诺姆和项链 (KMP)
Posted dwtfukgv
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51Nod 1554 欧姆诺姆和项链 (KMP)相关的知识,希望对你有一定的参考价值。
题意:中文题。
析:首先要使用KMP的失配函数 f ,对于长度为 i 的串,如果存在循环节那么 i % (i-f[i]) == 0,循环节的长度就是 i - f[i] ,当然次数就是 i / (i-f[i]),对于这个题,如果恰好是一个循环节,也就是 i % (i-f[i]) == 0,那么这个串一定是 SSSSSS...SSS的形式,要想出现 k+1 个 A,1 个A,可以看作是 k 个 AB和另外一个A,当然 A 可能是空串,也可能不是,那么要一共出现 k 次,也就是AB中一共包含 i / (i-f[i]) / k 个S,还剩下 i / (i-f[i]) % k, 这些就是剩下的,也就是那多出一个A,可以为空,只要满足,i / (i-f[i]) / k 大于或者等于i / (i-f[i]) % k ,如果不是正好循环节,也就是 i % (i-f[i]) != 0,这样的话就是 SSSS....SST,一定有一个T,也就是S的前缀,也就是A,而且肯定不为空,那么有了A,B也就有了同样求出一个AB中含有多少个S,再用总数减去T,就是B,因为T不为空,所以只要满足 i / (i-f[i]) / k 大于 i / (i-f[i]) % k 。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring> #include <set> #include <queue> #include <algorithm> #include <vector> #include <map> #include <cctype> #include <cmath> #include <stack> #include <sstream> #include <list> #include <assert.h> #define debug() puts("++++"); #define gcd(a, b) __gcd(a, b) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define fi first #define se second #define pb push_back #define sqr(x) ((x)*(x)) #define ms(a,b) memset(a, b, sizeof a) #define sz size() #define pu push_up #define pd push_down #define freopenr freopen("in.txt", "r", stdin) #define freopenw freopen("out.txt", "w", stdout) using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int, int> P; const int INF = 0x3f3f3f3f; const double inf = 1e20; const double PI = acos(-1.0); const double eps = 1e-8; const int maxn = 1e6 + 100; const int mod = 7600; const int dr[] = {-1, 0, 1, 0}; const int dc[] = {0, 1, 0, -1}; const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"}; int n, m; const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; inline bool is_in(int r, int c) { return r > 0 && r <= n && c > 0 && c <= m; } char s[maxn]; char ans[maxn]; int f[maxn]; void getFail(){ f[0] = f[1] = 0; ans[0] = ‘0‘; for(int i = 1; i < n; ++i){ ans[i] = ‘0‘; int j = f[i]; while(j && s[j] != s[i]) j = f[j]; f[i+1] = s[i] == s[j] ? j+1 : 0; } } int main(){ scanf("%d %d", &n, &m); scanf("%s", s); getFail(); for(int i = 1; i <= n; ++i){ int val = i / (i - f[i]); if(i % (i-f[i])){ if(val / m > val % m) ans[i-1] = ‘1‘; } else if(val / m >= val % m) ans[i-1] = ‘1‘; } puts(ans); return 0; } /* 14 5 ababababababab 00000000011100 14 3 ababababababab 00000111000111 20 7 ababbbaaabbbaaaabbbb 20 2 abababababababaaabab 00011101111111100000 */
以上是关于51Nod 1554 欧姆诺姆和项链 (KMP)的主要内容,如果未能解决你的问题,请参考以下文章