AT2155 [ARC064D] Rotated Palindromes
只有循环同构的字符串才能互相转换
考虑循环节的长度为 d d d,那么
- 若 d d d为偶数,那么如果循环 d / 2 d/2 d/2次会得到一个新的回文串,会计算重复,贡献为 d / 2 d/2 d/2
- 若为奇数,那么贡献为 d d d.可以随便循环
那么只需要计算出每个循环节长度为 d d d的字符串个数乘上面的贡献再求和就可以得到答案了
code:
#include<bits/stdc++.h>
#define ll long long
#define N 200050
#define mod 1000000007
using namespace std;
ll qpow(ll x, ll y) {
ll ret = 1;
for(; y; y >>= 1, x = x * x % mod) if(y & 1) ret = ret * x % mod;
return ret;
}
int n, k, d[N], tot, gs[N];
int main() {
scanf("%d%d", &n, &k);
for(int i = 1; i * i <= n; i ++) if(n % i == 0) {
d[++ tot] = i; if(i * i != n) d[++ tot] = n / i;
}
sort(d + 1, d + 1 + tot);
ll ans = 0;
for(int i = 1; i <= tot; i ++) {
gs[i] = qpow(k, (d[i] + 1) / 2);
for(int j = 1; j < i; j ++) if(d[i] % d[j] == 0) gs[i] = (gs[i] - gs[j] + mod) % mod;
if(d[i] & 1) ans = (ans + 1ll * d[i] * gs[i] % mod) % mod;
else ans = (ans + 1ll * (d[i] / 2) * gs[i] % mod) % mod;
}
printf("%lld", ans);
return 0;
}