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;
}
posted @ 2021-10-12 21:43  lahlah  阅读(33)  评论(0编辑  收藏  举报