1.求前缀等于后缀的长度,与pku2752一样。(kmp) 2.求2的幂,采用二分加记忆化。 #include<cstdio> #include<cstring> #define LL(a) (a<<1) #define RR(a) (a>>1) const int size = 100005; const int MOD = 10007; char word[size]; int P[size], Len; int power[size]={0}; void Init() { int j=-1, i; P[0] = -1; for (i = 1; i < Len; i++) { while(j >= 0 && word[j+1] != word[i]) j = P[j]; if (word[j+1] == word[i]) j++; P[i] = j; } } int Pow(int i) { if (power[i]) return power[i]; if (i&1) return power[i] = (Pow(RR(i)) * Pow(1+RR(i)))%MOD; else return power[i] = (Pow(RR(i)) * Pow(RR(i)))%MOD; } void Done() { for (int i = 2; i < 100; i++) power[i] = Pow(i); } int main() { int i, Num = 0, ans[size]; int total = 0; power[0] = 1; power[1] = 2; Done(); while (scanf("%s", word)!=EOF) { Len = strlen(word); Init(); Num = 0; i = Len - 1; total = 0; while(i != -1) { ans[Num++] = i+1; i = P[i]; } for (i = 0; i < Num; i++) { total += Pow(ans[i]); if (total >= MOD) total %= MOD; } printf("%d/n",total); } return 0; }