题意
给一个循环串,从某个点开始会得到一个字典序最小的串,从某个点开始会得到一个字典序最大的串,求这两个点的下标,以及其出现的次数。
思路
最小/大表示法求下标,kmp求出现次数。
Code
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e6+10;
int nxt[maxn], l;
char str[maxn<<1];
void getNxt(char *p) {
for (int i=1, j = 0; p[i]; ++i) {
while(j && p[i]!=p[j]) j = nxt[j-1];
if(p[i] == p[j]) ++j;
nxt[i] = j;
}
}
int solve(int op) { // 0: 最小表示法, 1:最大表示法
strncpy(str+l, str, l);
int i = 0, j = 1;
while(i < l && j < l) {
int k = 0;
while(k < l && str[i+k] == str[j+k]) ++k;
if(k >= l) break;
if((str[i+k] > str[j+k]) ^ op) i += k+1;
else j += k+1;
if(i == j) ++j;
}
return i < j ? i : j;
}
int main() {
while(scanf("%s", str)==1) {
getNxt(str);
l = strlen(str);
int len = l - nxt[l-1], cnt = l % len ? 1 : l/len;
int mi = solve(0), mx = solve(1);
printf("%d %d %d %d
", mi+1, cnt, mx+1, cnt);
}
return 0;
}