C♯の勉強

C♯4.0 で TopCoder の過去問を解きます。

TopCoder SRM603: PairsOfStrings

久しぶりに本番で通ったMedium。

A + C = C + B が成立するときは A は B を巡回シフトさせたものになる。
よって、もし A の文字列の最小周期が x だった場合は、対応するペアの個数は x になる。周期が x の文字列の個数は n % k == 0 のときは \(k^x\) 、それ以外の場合は \(0\)。

ただしこの値には約数の周期のパターン数も含まれているので、あとから取り除くようにする。

Practiceでは、BigInteger.ModPow を使って通してみた。

public class PairsOfStrings {
    const int mod = 1000000007;

    public List<int> Divisors(int x) {
        List<int> ret = new List<int>();
        for (int i = 1; i * i <= x; i++) {
            if (x % i == 0) {
                ret.Add(i);
                if (i != x / i) ret.Add(x / i);
            }
        }
        ret.Sort();
        return ret;
    }

    public int getNumber(int n, int k) {
        long ans = 0;
        var cyclePattern = new Dictionary<long, long>();
        var divisors = Divisors(n);
        foreach (int cycle in divisors) {
            long pattern = (long)BigInteger.ModPow(k, cycle, mod);
            foreach (int d in divisors) {
                if (cycle > d && cycle % d == 0) {
                    pattern = (pattern - cyclePattern[d] + mod) % mod;
                }
            }
            cyclePattern[cycle] = pattern;
            ans = (ans + pattern * cycle) % mod;
        }
        return (int)ans;
    }
}