Problem:
すぬけ君は，"
s
で
t
t
" というダジャレを思いついたが，忘れてしまった．すぬけ君は以下のことを覚えている．
s
の長さは
N
である．
t
の長さは
M
である．
t
は
s
の部分文字列である．(
s
の連続する
M
文字で
t
と一致している部分が存在する．)
(s, t)
として考えられる組み合わせの個数を 1,000,000,007 で割ったあまりを求めよ．ただし，文字は
A
種類存在するものとする．
Constraints
1 ≤
N
≤ 200
1 ≤
M
≤ 50
M
≤
N
1 ≤
A
≤ 1000
Input
N
M
A
Output
条件を満たす文字列の組
(s, t)
の個数を 1,000,000,007 で割ったあまりを出力せよ．
Sample Input 1
3 2 2
Sample Output 1
14
Sample Input 2
200 50 1000
Sample Output 2
678200960

Submitted solutions:

code_snippet: // AOJ #2637 Substring Pairs
// 2025.3.21

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int NMAX = 5010;
const int MOD = 1000000007;

int N, M, A;
int pw[NMAX], fa[NMAX], w[NMAX], f[NMAX];

int find(int x) {
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}

int get_s(ll s) {
    for (int i = 1; i <= M; i++) fa[i] = i;
    int cnt = 0;
    for (int i = 1; i < M; i++)
        if ((s >> i) & 1) for (int j = 1; j + i <= M; j++) fa[find(j)] = find(j + i);
    for (int i = 1; i <= M; i++) cnt += (find(i) == i);
    return cnt;
}

vector<ll> S;
void dfs(int k, ll s) {
    get_s(s);
    for (int i = 1; i < k; i++) {
        if (!((s >> i) & 1)) {
            bool diff = false;
            for (int j = 1; j + i <= M; j++) diff |= (find(j) != find(j + i));
            if (!diff) return;
        }
    }
    if (k == M) {
        S.push_back(s);
        return;
    }
    dfs(k + 1, s);
    dfs(k + 1, s | (1LL << k));
}

int calc(ll s, int res = 0) {
    for (int i = M, pre = 0; i <= N; i++) {
        pre = (1LL * pre * A % MOD + f[i - M]) % MOD;
        f[i] = (pw[i - M] + MOD - pre) % MOD;
        for (int j = 1; j < M; j++)
            if ((s >> j) & 1) (f[i] += MOD - f[i - j]) %= MOD;
        (res += 1LL * f[i] * pw[N - i] % MOD) %= MOD;
    }
    return res;
}

int main(){
    cin >> N >> M >> A;

    pw[0] = 1;
    for (int i = 1; i < NMAX; i++) pw[i] = 1LL * pw[i - 1] * A % MOD;
    dfs(1, 0);
    int ans = 0;
    reverse(S.begin(), S.end());
    for (int i = 0; i < (int)S.size(); i++) {
        w[i] = pw[get_s(S[i])];
        for (int j = 0; j < i; j++)
            if ((S[j] & S[i]) == S[i]) (w[i] += MOD - w[j]) %= MOD;
        (ans += 1LL * w[i] * calc(S[i]) % MOD) %= MOD;
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3540
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define inf 1000000007
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define fi first
#define se second
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define rrep(i,n) for(int i = (int)n-1; i >= 0; --i)
#define srep(i,a,b) for(int i = (int)a; i < (int)(b); ++i)
#define all(x) (x).begin(),(x).end()
#define SUM(v) accumulate(all(v), 0LL)
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end())
#define SZ(c) (int)(c).size()
template<typename T>
ostream& operator << (ostream& os, vector<T>& vec) {
    os << "{";
    for (int i = 0; i<(int)vec.size(); i++) {
        os << vec[i] << (i + 1 == (int)vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
// pair出力
template<typename T, typename U>
ostream& operator << (ostream& os, pair<T, U> pair_var) {
    os << "(" << pair_var.first << ", " << pair_var.second << ")";
    return os;
}
// map出力
template<typename T, typename U>
ostream& operator << (ostream& os, map<T, U>& map_var) {
    os << "{";
    for(auto itr = map_var.begin(); itr != map_var.end(); itr++){
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if(itr != map_var.end()) os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
// set 出力
template<typename T>
ostream& operator << (ostream& os, set<T>& set_var) {
    os << "{";
    for(auto itr = set_var.begin(); itr != set_var.end(); itr++){
        os << (*itr);
        ++itr;
        if(itr != set_var.end()) os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
// tuple 出力
template<int N,class Tuple>
void out(ostream &os,const Tuple &t){}
template<int N,class Tuple,class H,class ...Ts>
void out(ostream &os,const Tuple &t){
    if(N)os<<", ";
    os<<get<N>(t);
    out<N+1,Tuple,Ts...>(os,t);
}
template<class ...Ts>
ostream& operator<<(ostream &os, const tuple<Ts...> &t){
    os<<"(";
    out<0,tuple<Ts...>,Ts...>(os,t);
    os<<")";
    return os;
}
#define overload2(_1, _2, name, ...) name
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define VEC(type, name, size)                                                                                                                                  \
    vector<type> name(size);                                                                                                                                   \
    IN(name)
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define VV(type, name, h, w)                                                                                                                                   \
    vector<vector<type>> name(h, vector<type>(w));                                                                                                             \
    IN(name)
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)                                                                                                                         \
    vector<vector<vector<vector<type>>>> name(a, vector<vector<vector<type>>>(b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
#define INT(...)                                                                                                                                               \
    int __VA_ARGS__;                                                                                                                                           \
    IN(__VA_ARGS__)
#define LL(...)                                                                                                                                                \
    ll __VA_ARGS__;                                                                                                                                            \
    IN(__VA_ARGS__)
#define STR(...)                                                                                                                                               \
    string __VA_ARGS__;                                                                                                                                        \
    IN(__VA_ARGS__)
#define CHR(...)                                                                                                                                               \
    char __VA_ARGS__;                                                                                                                                          \
    IN(__VA_ARGS__)
#define DBL(...)                                                                                                                                               \
    double __VA_ARGS__;                                                                                                                                        \
    IN(__VA_ARGS__)
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(string &a) { cin >> a; }
template <class T, class S> void scan(pair<T, S> &p) { scan(p.first), scan(p.second); }
template <class T> void scan(vector<T> &);
template <class T> void scan(vector<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &...tail) {
    scan(head);
    IN(tail...);
}
const string YESNO[2] = {"NO", "YES"};
const string YesNo[2] = {"No", "Yes"};
const string yesno[2] = {"no", "yes"};
void YES(bool t = 1) { cout << YESNO[t] << endl; }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { cout << YesNo[t] << endl; }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { cout << yesno[t] << endl; }
void no(bool t = 1) { yes(!t); }
#ifdef LOCAL
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << H;
    debug_out(T...);
}
#define dbg(...) \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define dbg(...) (void(0))
#define dump(x) (void(0))
#endif
template<typename A, typename T>
std::enable_if_t<std::is_convertible<T, A>::value> fill(A& array, const T& val)
{
    array = val;
}
template<typename A, typename T>
std::enable_if_t<!std::is_convertible<T, A>::value> fill(A& array, const T& val)
{
    for (auto& a : array) {
        fill(a, val);
    }
}
template <typename T, typename S> T ceil(T x, S y) {
    assert(y);
    return (y < 0 ? ceil(-x, -y) : (x > 0 ? (x + y - 1) / y : x / y));
}
template <typename T, typename S> T floor(T x, S y) {
    assert(y);
    return (y < 0 ? floor(-x, -y) : (x > 0 ? x / y : x / y - (x % y == 0 ? 0 : 1)));
}
vector<int> iota(int n) {vector<int> a(n);iota(all(a), 0);return a;}
template <class T> T POW(T x, int n) {T res = 1;for(; n; n >>= 1, x *= x){if(n & 1) res *= x;}return res;}
ll pow2(int i) { return 1LL << i; }
int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(ll t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int lowbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int lowbit(ll a) { return a == 0 ? 64 : __builtin_ctzll(a); }
// int allbit(int n) { return (1 << n) - 1; }
ll allbit(ll n) { return (1LL << n) - 1; }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(ll t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }


template <class S> void fold_in(vector<S> &v) {}
template <typename Head, typename... Tail, class S> void fold_in(vector<S> &v, Head &&a, Tail &&...tail) {
    for(auto e : a) v.emplace_back(e);
    fold_in(v, tail...);
}
template <class S> void renumber(vector<S> &v) {}
template <typename Head, typename... Tail, class S> void renumber(vector<S> &v, Head &&a, Tail &&...tail) {
    for(auto &&e : a) e = lb(v, e);
    renumber(v, tail...);
}
template <class S, class... Args> void zip(vector<S> &head, Args &&...args) {
    vector<S> v;
    fold_in(v, head, args...);
    sort(all(v)), v.erase(unique(all(v)), v.end());
    renumber(v, head, args...);
}
template<class T> inline bool chmax(T &a, T b){
    if(a<b){
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmin(T &a, T b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}


template <unsigned int mod>
class ModInt {
private:
    unsigned int v;
    static unsigned int norm(const unsigned int& x){ return x < mod ? x : x - mod; }
    static ModInt make(const unsigned int& x){ ModInt m; return m.v = x, m; }
    static ModInt inv(const ModInt& x){ return make(inverse(x.v, mod)); }
    static unsigned int inverse(int a, int m){
        int u[] = {a, 1, 0}, v[] = {m, 0, 1}, t;
        while(*v){
            t = *u / *v;
            swap(u[0] -= t * v[0], v[0]), swap(u[1] -= t * v[1], v[1]), swap(u[2] -= t * v[2], v[2]);
        }
        return (u[1] % m + m) % m;
    }

public:
    ModInt() : v{0}{}
    ModInt(const long long val) : v{norm(val % mod + mod)} {}
    ModInt(const ModInt<mod>& n) : v{n()} {}
    explicit operator bool() const noexcept { return v != 0; }
    bool operator!() const noexcept { return !static_cast<bool>(*this); }
    ModInt& operator=(const ModInt& n){ return v = n(), (*this); }
    ModInt& operator=(const long long val){ return v = norm(val % mod + mod), (*this); }
    ModInt operator+() const { return *this; }
    ModInt operator-() const { return v == 0 ? make(0) : make(mod - v); }
    ModInt operator+(const ModInt& val) const { return make(norm(v + val())); }
    ModInt operator-(const ModInt& val) const { return make(norm(v + mod - val())); }
    ModInt operator*(const ModInt& val) const { return make((long long)v * val() % mod); }
    ModInt operator/(const ModInt& val) const { return *this * inv(val); }
    ModInt& operator+=(const ModInt& val){ return *this = *this + val; }
    ModInt& operator-=(const ModInt& val){ return *this = *this - val; }
    ModInt& operator*=(const ModInt& val){ return *this = *this * val; }
    ModInt& operator/=(const ModInt& val){ return *this = *this / val; }
    ModInt operator+(const long long val) const { return ModInt{v + val}; }
    ModInt operator-(const long long val) const { return ModInt{v - val}; }
    ModInt operator*(const long long val) const { return ModInt{(long long)v * (val % mod)}; }
    ModInt operator/(const long long val) const { return ModInt{(long long)v * inv(val)}; }
    ModInt& operator+=(const long long val){ return *this = *this + val; }
    ModInt& operator-=(const long long val){ return *this = *this - val; }
    ModInt& operator*=(const long long val){ return *this = *this * val; }
    ModInt& operator/=(const long long val){ return *this = *this / val; }
    bool operator==(const ModInt& val) const { return v == val.v; }
    bool operator!=(const ModInt& val) const { return !(*this == val); }
    bool operator==(const long long val) const { return v == norm(val % mod + mod); }
    bool operator!=(const long long val) const { return !(*this == val); }
    unsigned int operator()() const { return v; }
    friend ModInt operator+(const long long val, const ModInt& n) { return n + val; }
    friend ModInt operator-(const long long val, const ModInt& n) { return ModInt{val - n()}; }
    friend ModInt operator*(const long long val, const ModInt& n) { return n * val; }
    friend ModInt operator/(const long long val, const ModInt& n) { return ModInt{val} / n; }
    friend bool operator==(const long long val, const ModInt& n) { return n == val; }
    friend bool operator!=(const long long val, const ModInt& n) { return !(val == n); }
    friend istream& operator>>(istream& is, ModInt& n){
        unsigned int v;
        return is >> v, n = v, is;
    }
    friend ostream& operator<<(ostream& os, const ModInt& n){ return (os << n()); }
    friend ModInt mod_pow(ModInt x, long long n){
        ModInt ans = 1;
        while(n){
            if(n & 1) ans *= x;
            x *= x, n >>= 1;
        }
        return ans;
    }
};

#define MOD 1000000007
using mod = ModInt<MOD>;

#define MAX_N 200000
mod inv[MAX_N],fac[MAX_N],finv[MAX_N];

void make()
{
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for(int i=2;i<MAX_N;i++){
        inv[i] = MOD - inv[MOD % i] * (MOD / i);
        fac[i] = fac[i-1] * i;
        finv[i] = finv[i-1] * inv[i];
    }
}

mod comb(int a, int b)
{
    if(a<b) return 0;
    return fac[a] * finv[b] * finv[a-b];
}

class UnionFind {
private:
    int sz;
    vector<int> par, size_;
public:
    UnionFind(){}
    UnionFind(int node_size) : sz(node_size), par(sz), size_(sz, 1){
        iota(par.begin(), par.end(), 0);
    }
    int find(int x){
        if(par[x] == x) return x;
        else return par[x] = find(par[x]);
    }
    void unite(int x,int y){
        x = find(x), y = find(y);
        if(x == y) return;
        if(size_[x] < size_[y]) swap(x,y);
        par[y] = x;
        size_[x] += size_[y];
    }
    int size(int x){
        x = find(x);
        return size_[x];
    }
    bool same(int x,int y){
        return find(x) == find(y);
    }
};




int main(){
    INT(n,m,A);
    vector<ll> P;
    map<int,vector<ll>> mp;
    auto dfs = [&](auto&&f, int len) -> vector<ll> {
        if(len==1)return {1};
        if(mp.find(len)!=mp.end()){
            return mp[len];
        }
        vector<ll> tmp;
        tmp.push_back((1LL<<(len-1)));
        for(int i=1;i<len;i++){
            int C = len/i;
            if(C==1){
                int d = len - C*i;
                auto X = f(f,d);
                ll T = (1LL<<(len-1))|(1LL<<(len-1-i));
                for(auto x:X){
                    tmp.push_back(T|x);
                }
                
                continue;
            }
            auto X = f(f,len - C*i + i);
            ll T = 0;
            for(int k=len-1;k>=0;k -=i){
                T |= (1LL<<k);
            }
            for(auto x:X){
                tmp.push_back(T|x);
            }
           
        }
        return mp[len] = tmp;
    };
    P = dfs(dfs,m);
    UNIQUE(P);
    sort(all(P));
    reverse(all(P));
    vector<mod> S;
    for(auto bits:P){
        UnionFind uf(m);
        rep(i,m){
            if((bits>>i)&1){
                for(int j=0;j<=i;j++){
                    uf.unite(j,m-1-i+j);
                }
            }
        }
        int c = 0;
        rep(i,m)c += uf.find(i) == i;
        S.push_back(mod_pow((mod)A,c));
    }
    int T = 0;
    vector<ll> Q;
    vector<mod> SS;
    rep(i,P.size()){
        rep(j,i){
            if((P[i]&P[j]) == P[i]){
                S[i] -= S[j];
            }
        }
        if(S[i]!=0){
            Q.push_back(P[i]);
            SS.push_back(S[i]);
        }
    }
    mod res = 0;
    P = Q;
    S = SS;
    rep(z,P.size()){
        ll bits = P[z];
        vvv(mod,dp,n+1,2,2);
        dp[0][0][0] = 1;
        rep(i,n){
            rep(c,2){
                rep(k,m-1){
                    if((bits>>k)&1){
                        int len = m - k - 1;
                        if(i+len <= n)dp[i+len][(c+1)%2][1] += dp[i][c][1];
                    }
                }
                dp[i+1][c][0] += dp[i][c][1] * A;
                dp[i+1][c][0] += dp[i][c][0] * A;
                if(i+m<=n)dp[i+m][(c+1)%2][1] += dp[i][c][0] + dp[i][c][1];
            }
        }
        res += S[z] * (mod_pow((mod)A,n) - (dp[n][0][0] + dp[n][0][1] - dp[n][1][0] - dp[n][1][1]));
    }
    cout << res << endl;
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 6324
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define inf 1000000007
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define fi first
#define se second
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define rrep(i,n) for(int i = (int)n-1; i >= 0; --i)
#define srep(i,a,b) for(int i = (int)a; i < (int)(b); ++i)
#define all(x) (x).begin(),(x).end()
#define SUM(v) accumulate(all(v), 0LL)
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end())
#define SZ(c) (int)(c).size()
template<typename T>
ostream& operator << (ostream& os, vector<T>& vec) {
    os << "{";
    for (int i = 0; i<(int)vec.size(); i++) {
        os << vec[i] << (i + 1 == (int)vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
// pair出力
template<typename T, typename U>
ostream& operator << (ostream& os, pair<T, U> pair_var) {
    os << "(" << pair_var.first << ", " << pair_var.second << ")";
    return os;
}
// map出力
template<typename T, typename U>
ostream& operator << (ostream& os, map<T, U>& map_var) {
    os << "{";
    for(auto itr = map_var.begin(); itr != map_var.end(); itr++){
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if(itr != map_var.end()) os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
// set 出力
template<typename T>
ostream& operator << (ostream& os, set<T>& set_var) {
    os << "{";
    for(auto itr = set_var.begin(); itr != set_var.end(); itr++){
        os << (*itr);
        ++itr;
        if(itr != set_var.end()) os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
// tuple 出力
template<int N,class Tuple>
void out(ostream &os,const Tuple &t){}
template<int N,class Tuple,class H,class ...Ts>
void out(ostream &os,const Tuple &t){
    if(N)os<<", ";
    os<<get<N>(t);
    out<N+1,Tuple,Ts...>(os,t);
}
template<class ...Ts>
ostream& operator<<(ostream &os, const tuple<Ts...> &t){
    os<<"(";
    out<0,tuple<Ts...>,Ts...>(os,t);
    os<<")";
    return os;
}
#define overload2(_1, _2, name, ...) name
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define VEC(type, name, size)                                                                                                                                  \
    vector<type> name(size);                                                                                                                                   \
    IN(name)
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define VV(type, name, h, w)                                                                                                                                   \
    vector<vector<type>> name(h, vector<type>(w));                                                                                                             \
    IN(name)
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)                                                                                                                         \
    vector<vector<vector<vector<type>>>> name(a, vector<vector<vector<type>>>(b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
#define INT(...)                                                                                                                                               \
    int __VA_ARGS__;                                                                                                                                           \
    IN(__VA_ARGS__)
#define LL(...)                                                                                                                                                \
    ll __VA_ARGS__;                                                                                                                                            \
    IN(__VA_ARGS__)
#define STR(...)                                                                                                                                               \
    string __VA_ARGS__;                                                                                                                                        \
    IN(__VA_ARGS__)
#define CHR(...)                                                                                                                                               \
    char __VA_ARGS__;                                                                                                                                          \
    IN(__VA_ARGS__)
#define DBL(...)                                                                                                                                               \
    double __VA_ARGS__;                                                                                                                                        \
    IN(__VA_ARGS__)
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(string &a) { cin >> a; }
template <class T, class S> void scan(pair<T, S> &p) { scan(p.first), scan(p.second); }
template <class T> void scan(vector<T> &);
template <class T> void scan(vector<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &...tail) {
    scan(head);
    IN(tail...);
}
const string YESNO[2] = {"NO", "YES"};
const string YesNo[2] = {"No", "Yes"};
const string yesno[2] = {"no", "yes"};
void YES(bool t = 1) { cout << YESNO[t] << endl; }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { cout << YesNo[t] << endl; }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { cout << yesno[t] << endl; }
void no(bool t = 1) { yes(!t); }
#ifdef LOCAL
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << H;
    debug_out(T...);
}
#define dbg(...) \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define dbg(...) (void(0))
#define dump(x) (void(0))
#endif
template<typename A, typename T>
std::enable_if_t<std::is_convertible<T, A>::value> fill(A& array, const T& val)
{
    array = val;
}
template<typename A, typename T>
std::enable_if_t<!std::is_convertible<T, A>::value> fill(A& array, const T& val)
{
    for (auto& a : array) {
        fill(a, val);
    }
}
template <typename T, typename S> T ceil(T x, S y) {
    assert(y);
    return (y < 0 ? ceil(-x, -y) : (x > 0 ? (x + y - 1) / y : x / y));
}
template <typename T, typename S> T floor(T x, S y) {
    assert(y);
    return (y < 0 ? floor(-x, -y) : (x > 0 ? x / y : x / y - (x % y == 0 ? 0 : 1)));
}
vector<int> iota(int n) {vector<int> a(n);iota(all(a), 0);return a;}
template <class T> T POW(T x, int n) {T res = 1;for(; n; n >>= 1, x *= x){if(n & 1) res *= x;}return res;}
ll pow2(int i) { return 1LL << i; }
int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(ll t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int lowbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int lowbit(ll a) { return a == 0 ? 64 : __builtin_ctzll(a); }
// int allbit(int n) { return (1 << n) - 1; }
ll allbit(ll n) { return (1LL << n) - 1; }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(ll t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }


template <class S> void fold_in(vector<S> &v) {}
template <typename Head, typename... Tail, class S> void fold_in(vector<S> &v, Head &&a, Tail &&...tail) {
    for(auto e : a) v.emplace_back(e);
    fold_in(v, tail...);
}
template <class S> void renumber(vector<S> &v) {}
template <typename Head, typename... Tail, class S> void renumber(vector<S> &v, Head &&a, Tail &&...tail) {
    for(auto &&e : a) e = lb(v, e);
    renumber(v, tail...);
}
template <class S, class... Args> void zip(vector<S> &head, Args &&...args) {
    vector<S> v;
    fold_in(v, head, args...);
    sort(all(v)), v.erase(unique(all(v)), v.end());
    renumber(v, head, args...);
}
template<class T> inline bool chmax(T &a, T b){
    if(a<b){
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmin(T &a, T b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}


template <unsigned int mod>
class ModInt {
private:
    unsigned int v;
    static unsigned int norm(const unsigned int& x){ return x < mod ? x : x - mod; }
    static ModInt make(const unsigned int& x){ ModInt m; return m.v = x, m; }
    static ModInt inv(const ModInt& x){ return make(inverse(x.v, mod)); }
    static unsigned int inverse(int a, int m){
        int u[] = {a, 1, 0}, v[] = {m, 0, 1}, t;
        while(*v){
            t = *u / *v;
            swap(u[0] -= t * v[0], v[0]), swap(u[1] -= t * v[1], v[1]), swap(u[2] -= t * v[2], v[2]);
        }
        return (u[1] % m + m) % m;
    }

public:
    ModInt() : v{0}{}
    ModInt(const long long val) : v{norm(val % mod + mod)} {}
    ModInt(const ModInt<mod>& n) : v{n()} {}
    explicit operator bool() const noexcept { return v != 0; }
    bool operator!() const noexcept { return !static_cast<bool>(*this); }
    ModInt& operator=(const ModInt& n){ return v = n(), (*this); }
    ModInt& operator=(const long long val){ return v = norm(val % mod + mod), (*this); }
    ModInt operator+() const { return *this; }
    ModInt operator-() const { return v == 0 ? make(0) : make(mod - v); }
    ModInt operator+(const ModInt& val) const { return make(norm(v + val())); }
    ModInt operator-(const ModInt& val) const { return make(norm(v + mod - val())); }
    ModInt operator*(const ModInt& val) const { return make((long long)v * val() % mod); }
    ModInt operator/(const ModInt& val) const { return *this * inv(val); }
    ModInt& operator+=(const ModInt& val){ return *this = *this + val; }
    ModInt& operator-=(const ModInt& val){ return *this = *this - val; }
    ModInt& operator*=(const ModInt& val){ return *this = *this * val; }
    ModInt& operator/=(const ModInt& val){ return *this = *this / val; }
    ModInt operator+(const long long val) const { return ModInt{v + val}; }
    ModInt operator-(const long long val) const { return ModInt{v - val}; }
    ModInt operator*(const long long val) const { return ModInt{(long long)v * (val % mod)}; }
    ModInt operator/(const long long val) const { return ModInt{(long long)v * inv(val)}; }
    ModInt& operator+=(const long long val){ return *this = *this + val; }
    ModInt& operator-=(const long long val){ return *this = *this - val; }
    ModInt& operator*=(const long long val){ return *this = *this * val; }
    ModInt& operator/=(const long long val){ return *this = *this / val; }
    bool operator==(const ModInt& val) const { return v == val.v; }
    bool operator!=(const ModInt& val) const { return !(*this == val); }
    bool operator==(const long long val) const { return v == norm(val % mod + mod); }
    bool operator!=(const long long val) const { return !(*this == val); }
    unsigned int operator()() const { return v; }
    friend ModInt operator+(const long long val, const ModInt& n) { return n + val; }
    friend ModInt operator-(const long long val, const ModInt& n) { return ModInt{val - n()}; }
    friend ModInt operator*(const long long val, const ModInt& n) { return n * val; }
    friend ModInt operator/(const long long val, const ModInt& n) { return ModInt{val} / n; }
    friend bool operator==(const long long val, const ModInt& n) { return n == val; }
    friend bool operator!=(const long long val, const ModInt& n) { return !(val == n); }
    friend istream& operator>>(istream& is, ModInt& n){
        unsigned int v;
        return is >> v, n = v, is;
    }
    friend ostream& operator<<(ostream& os, const ModInt& n){ return (os << n()); }
    friend ModInt mod_pow(ModInt x, long long n){
        ModInt ans = 1;
        while(n){
            if(n & 1) ans *= x;
            x *= x, n >>= 1;
        }
        return ans;
    }
};

#define MOD 1000000007
using mod = ModInt<MOD>;

#define MAX_N 200000
mod inv[MAX_N],fac[MAX_N],finv[MAX_N];

void make()
{
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for(int i=2;i<MAX_N;i++){
        inv[i] = MOD - inv[MOD % i] * (MOD / i);
        fac[i] = fac[i-1] * i;
        finv[i] = finv[i-1] * inv[i];
    }
}

mod comb(int a, int b)
{
    if(a<b) return 0;
    return fac[a] * finv[b] * finv[a-b];
}

class UnionFind {
private:
    int sz;
    vector<int> par, size_;
public:
    UnionFind(){}
    UnionFind(int node_size) : sz(node_size), par(sz), size_(sz, 1){
        iota(par.begin(), par.end(), 0);
    }
    int find(int x){
        if(par[x] == x) return x;
        else return par[x] = find(par[x]);
    }
    void unite(int x,int y){
        x = find(x), y = find(y);
        if(x == y) return;
        if(size_[x] < size_[y]) swap(x,y);
        par[y] = x;
        size_[x] += size_[y];
    }
    int size(int x){
        x = find(x);
        return size_[x];
    }
    bool same(int x,int y){
        return find(x) == find(y);
    }
};




int main(){
    INT(n,m,A);
    vector<ll> P;
    map<int,vector<ll>> mp;
    auto dfs = [&](auto&&f, int len) -> vector<ll> {
        if(len==1)return {1};
        if(mp.find(len)!=mp.end()){
            return mp[len];
        }
        vector<ll> tmp;
        tmp.push_back((1LL<<(len-1)));
        for(int i=1;i<len;i++){
            int C = len/i;
            if(C==1){
                int d = len - C*i;
                auto X = f(f,d);
                ll T = (1LL<<(len-1))|(1LL<<(len-1-i));
                for(auto x:X){
                    tmp.push_back(T|x);
                }
                
                continue;
            }
            auto X = f(f,len - C*i + i);
            ll T = 0;
            for(int k=len-1;k>=0;k -=i){
                T |= (1LL<<k);
            }
            for(auto x:X){
                tmp.push_back(T|x);
            }
           
        }
        return mp[len] = tmp;
    };
    P = dfs(dfs,m);
    UNIQUE(P);
    sort(all(P));
    reverse(all(P));
    // cerr << P.size() << endl;
    vector<mod> S;
    for(auto bits:P){
        UnionFind uf(m);
        rep(i,m){
            if((bits>>i)&1){
                for(int j=0;j<=i;j++){
                    uf.unite(j,m-1-i+j);
                }
            }
        }
        int c = 0;
        rep(i,m)c += uf.find(i) == i;
        S.push_back(mod_pow((mod)A,c));
    }
    int T = 0;
    vector<ll> Q;
    vector<mod> SS;
    rep(i,P.size()){
        rep(j,i){
            if((P[i]&P[j]) == P[i]){
                S[i] -= S[j];
            }
        }
        if(S[i]!=0){
            Q.push_back(P[i]);
            SS.push_back(S[i]);
        }
    }
    mod res = 0;
    P = Q;
    S = SS;
    // cerr << P.size() << endl;
    rep(z,P.size()){
        ll bits = P[z];
        vvv(mod,dp,n+1,2,2);
        dp[0][0][0] = 1;
        rep(i,n){
            rep(c,2){
                rep(k,m-1){
                    if((bits>>k)&1){
                        int len = m - k - 1;
                        if(i+len <= n)dp[i+len][(c+1)%2][1] += dp[i][c][1];
                    }
                }
                dp[i+1][c][0] += dp[i][c][1] * A;
                dp[i+1][c][0] += dp[i][c][0] * A;
                if(i+m<=n)dp[i+m][(c+1)%2][1] += dp[i][c][0] + dp[i][c][1];
            }
        }
        // cerr << dp[n][0][0] << " " << dp[n][0][1] << " " << dp[n][1][0] << " " << dp[n][1][1] << endl;
        // cerr << bitset<5>(bits) << " " << S[z] << " " << mod_pow((mod)A,n) - (dp[n][0][0] + dp[n][0][1] - dp[n][1][0] - dp[n][1][1]) << endl;
        res += S[z] * (mod_pow((mod)A,n) - (dp[n][0][0] + dp[n][0][1] - dp[n][1][0] - dp[n][1][1]));

    }
    cout << res << endl;
    
    // int C = 0;
    
    // vector<vector<int> > X;
    // vector<vector<int> > Y;
    // vector<int> x(n);
    // auto dfs2 = [&](auto&&f,int id, bool p) -> void {
    //     if(p){
    //         if(id==n){
    //             X.push_back(x);
    //             return;
    //         }
    //     }else{
    //         if(id==m){
    //             Y.push_back(x);
    //             return;
    //         }
    //     }
    //     rep(i,A){
    //         x[id] = i;
    //         f(f,id+1,p);
    //     }
    // };
    // dfs2(dfs2,0,1);
    // x.resize(m);
    // dfs2(dfs2,0,0);
    
    // for(auto y:Y){
    //     string s;
    //     rep(i,m){
    //         bool flag = true;
    //         rep(j,m-i){
    //             if(y[j]!=y[i+j]){
    //                 flag = false;
    //                 break;
    //             }
    //         }
    //         s.push_back('0' + flag);
    //     }
    //     int D = 0;
    //     for(auto x:X){
    //         rep(i,n-m + 1){
    //             bool flag = true;
    //             rep(j,m){
    //                 if(x[i+j] != y[j]){
    //                     flag = false;
    //                     break;
    //                 }
    //             }
    //             if(flag){
    //                 D++;
    //                 break;
    //             }
    //         }
    //     }
    //     cerr << s << " " << D << endl;
    //     C += D;
    // }
    // cerr << C << endl;
    // int C = 0;

    // rep(cbits,1<<m){
    //     string s;
    //     rep(i,m){
    //         if((cbits>>i) == (cbits&((1<<(m-i))-1))){
    //             s.push_back('1');
    //         }else{
    //             s.push_back('0');
    //         }
    //     }
    //     int D = 0;
    //     rep(bits,1<<n){
    //         bool f = 0;
    //         rep(i,n-m + 1){
    //             if(((bits>>i)&((1<<m) - 1)) == cbits)f = 1;
    //         }
    //         if(f)D++;
    //     }
    //     // cerr << s << " " << D << endl;
    //     C += D;
    // }
    // cerr << C << endl;
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 6300
final_rank: 4

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
#include<chrono>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);

template<typename T>
void chmin(T& a, T b) {
	a = min(a, b);
}
template<typename T>
void chmax(T& a, T b) {
	a = max(a, b);
}
template<typename T>
void cinarray(vector<T>& v) {
	rep(i, v.size())cin >> v[i];
}
template<typename T>
void coutarray(vector<T>& v) {
	rep(i, v.size()) {
		if (i > 0)cout << " "; cout << v[i];
	}
	cout << "\n";
}
ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	if (x == 0)return 0;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	int n;
	modint() :n(0) { ; }
	modint(ll m) {
		if (m < 0 || mod <= m) {
			m %= mod; if (m < 0)m += mod;
		}
		n = m;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

ll gcd(ll a, ll b) {
	a = abs(a); b = abs(b);
	if (a < b)swap(a, b);
	while (b) {
		ll r = a % b; a = b; b = r;
	}
	return a;
}

int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };


void expr() {
	int sum = 0;
	ll cur = 1;
	ll ans = 0;
	function<void(int)> dfs = [&](int dep) {
		if (dep == 50) {
			ans++; 
			if (ans % 10000 == 0)cout << ans << "\n";
			return;
		}
		dfs(dep + 1);
		int memsum = sum;
		ll memcur = cur;
		if (sum + dep+dep+1 <= 200 && (cur & (1ll << dep)) == 0) {
			sum += dep;
			for (int j = 0; j + dep < 50; j++) {
				if (cur & (1ll << j)) {
					cur |= (1ll << (j + dep));
				}
			}
			dfs(dep + 1);
			sum = memsum;
			cur = memcur;
		}
	};
	dfs(1);
	cout << ans << "\n";
}
void expr2(int m) {
	int sum = 0;
	ll cur = 1;
	ll ans = 0;
	function<void(int)> dfs = [&](int dep) {
		if (dep == m) {
			ans++;
			return;
		}
		dfs(dep + 1);
		int memsum = sum;
		ll memcur = cur;
		if (sum + dep + m <= 200 && (cur & (1ll << dep)) == 0) {
			sum += dep;
			for (int j = 0; j + dep < m; j++) {
				if (cur & (1ll << j)) {
					cur |= (1ll << (j + dep));
				}
			}
			dfs(dep + 1);
			sum = memsum;
			cur = memcur;
		}
	};
	dfs(1);
	cout << ans << "\n";
}

vector<vector<int>> G;
map<vector<int>, int> mp;
void expr3(int m,int n=200) {
	vector<int> ori(m);
	rep(i, m)ori[i] = i;
	vector<set<vector<int>>> que(n - m + 1);
	que[0].insert(ori);
	set <vector<int>> ald;
	mp[ori] = 0;
	G.push_back({});
	for (int i = 0; i < n - m + 1;i++) {
		for (vector<int> v : que[i]) {
			if (ald.find(v) != ald.end())continue;
			ald.insert(v);
			int id = mp[v];
			G[id].resize(n - m + 1);

			int ma = 0; rep(i, m)chmax(ma, v[i]); ma++;
			vector<vector<int>> loc(ma);
			rep(i, m) {
				loc[v[i]].push_back(i);
			}
			for (int ad = 1; ad < m; ad++) {
				if (i + ad >= n - m + 1)continue;
				
				vector<bool> used(m + ma);
				vector<int> cur(m);
				int tmp = 0;
				rep(i, m)if (!used[i]) {
					queue<int> q; q.push(i); used[i] = true;
					while (!q.empty()) {
						int id = q.front(); q.pop();
						if (id < m) {
							cur[id] = tmp;
							if (!used[v[id]+m]) {
								used[v[id]+m] = true;
								q.push(v[id]+m);
							}
							if (id - ad >= 0 && !used[id - ad]) {
								used[id - ad] = true;
								q.push(id - ad);
							}
							if (id + ad < m && !used[id + ad]) {
								used[id + ad] = true;
								q.push(id + ad);
							}
						}
						else {
							for (int to : loc[id - m]) {
								if (!used[to]) {
									used[to] = true;
									q.push(to);
								}
							}
						}
					}
					tmp++;
				}
				
				//rep(i, ma)assert(used[i + m]);
				if (mp.find(cur) == mp.end()) {
					G.push_back({});
					int sz = mp.size();
					mp[cur] = sz;
				}
				if (!ald.count(cur)) {
					que[i + ad].insert(cur);
				}
				G[id][ad] = mp[cur];
			}
		}
	}
	//assert(mp.size() == G.size());
	//cout << mp.size() << "\n";
}
void useexpr() {
	for (int m = 1; m <= 50; m++) {
		cout << "! "<<m << "\n";
		expr2(m);
		expr3(m);
	}
}

modint dp[205][1800][2];
void solve() {
	int n, m, a; cin >> n >> m >> a;
	expr3(m);
	vector<modint> ta(n + 1);
	ta[0] = 1;
	rep(i, n) {
		ta[i + 1] = ta[i] * (modint)a;
	}
	for (int i = 0; i < n - m + 1; i++) {
		//start
		dp[i][0][1] += ta[i];
		//kubaru
		rep(j, G.size()) {
			rep(l, 2) {
				if (dp[i][j][l] == (modint)0)continue;
				for (int to = i + 1; to <= n - m + 1; to++) {
					int dif = to - i;
					if (dif >= m) {
						dp[to][j][l ^ 1] += dp[i][j][l] * ta[dif - m];
					}
					else {
						dp[to][G[j][dif]][l ^ 1] += dp[i][j][l];
					}
				}
			}
		}
	}
	vector<modint> coef(G.size());
	for (auto p : mp) {
		int ma = 0;
		rep(i, m) {
			chmax(ma, p.first[i]);
		}
		ma++;
		coef[p.second] = ta[ma];
	}
	//coutarray(coef);
	modint ans = 0;
	rep(i, n - m + 1) {
		rep(j, G.size())rep(l, 2) {
			if (dp[i][j][l] == (modint)0)continue;
			modint val = dp[i][j][l] * ta[n - m - i]*coef[j];
			if (l == 0)val *= -1;
			//cout << "? " << i << " " << val << "\n";
			ans += val;
		}
	}
	cout << ans << "\n";
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(10);
	init_f();
	//init();
	//while(true)
	//useexpr();
	//init(50);
	//init();
	//int t; cin >> t; rep(i, t)
	//while (cin >> m >> n >> s >> w, m + n)
		solve();
	return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 16832
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define mod 1000000007
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
vector<vector<int> >pat[55];
vector<vector<int> >rec(int num){
	if(num <= 1){
		vector<vector<int> >ret;
		ret.pb(vector<int>());
		return pat[num] = ret;
	}
	if(pat[num].size()) return pat[num];
	pat[num].pb(vector<int>());
	for(int i=1;i<num;i++){
		vector<int>hoge;
		int zan = num;
		for(int j=i;(j == i || zan >= 2*i);j+=i){
			hoge.pb(j);
			zan -= i;
		}
		vector<vector<int> >pl = rec(zan);
		for(int j=0;j<pl.size();j++){
			vector<int>vi = hoge;
			for(int k=0;k<pl[j].size();k++) vi.pb(hoge[hoge.size()-1]+pl[j][k]);
			pat[num].pb(vi);
		}
	}
	return pat[num];
}
int s,t,n;
int dp[(1<<15)];
bitset<64>ok[(1<<15)];
struct UF{
	int par[55],ran[55];
	void init(){ for(int i=0;i<55;i++) par[i] = i; }
	int find(int x){ if(x == par[x]) return x; else return par[x] = find(par[x]); }
	void unite(int x,int y){
		x = find(x); y = find(y); if(x==y) return;
		if(ran[x] < ran[y]) par[x] = y;
		else{
			par[y] = x;
			if(ran[x] == ran[y]) ran[x]++;
		}
	}
	bool same(int x,int y){ return find(x)==find(y); }
}uf[(1<<15)];
bool cmp(const vector<int>& a,const vector<int>& b){
	return a.size() > b.size();
}
ll DP[205][2];
int main(){
	cin>>s>>t>>n;
	rec(t);
	sort(pat[t].begin(),pat[t].end(),cmp);
	for(int i=0;i<pat[t].size();i++){
		uf[i].init();
		for(int j=0;j<pat[t][i].size();j++){
			ok[i][pat[t][i][j]] = 1;
			int a = pat[t][i][j];
			assert(1<=a && a<t);
			for(int k=0;k+a<t;k++) uf[i].unite(k,k+a);
		}
		ll x = 1;
		for(int k=0;k<t;k++){
			if(uf[i].find(k) == k){
				x = x*1LL*n%mod;
			}
		}
		dp[i] = int(x);
		for(int j=0;j<i;j++){
			if((ok[j]&ok[i]) == ok[i]){
				dp[i] -= dp[j];
				if(dp[i] < 0) dp[i] += mod;
			}
		}
	}
	ll ans = 0;
	for(int i=0;i<pat[t].size();i++){
		for(int j=0;j<=s;j++) DP[j][0] = DP[j][1] = 0;
		DP[0][0] = 1;
		ll cur[2] = {};
		cur[0] = 1;
		ll res = 0;
		for(int j=1;j<=s-t+1;j++){
			for(int k=0;k<2;k++){
				DP[j][k] += cur[1-k];
				for(int a=0;a<pat[t][i].size();a++){
					if(j-pat[t][i][a] <= 0) break;
					DP[j][k] += DP[j-pat[t][i][a]][1-k];
				}
				DP[j][k] %= mod;
			}
			cur[0] = cur[0]*1LL*n%mod;
			cur[1] = cur[1]*1LL*n%mod;
			if(j>=t){
				cur[0] = (cur[0]+DP[j-t+1][0])%mod;
				cur[1] = (cur[1]+DP[j-t+1][1])%mod;
			}
		}
		ll tg = 1;
		for(int j=s-t+1;j>=1;j--){
			res += DP[j][1] * tg % mod;
			res -= DP[j][0] * tg % mod;
			tg = tg*1LL*n%mod;
		}
		res %= mod;
		ans += dp[i]*res%mod;
	}
	cout << (ans%mod+mod)%mod << endl;
}
accuracy: 1
time_ms: 190
memory_kb: 16296
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define mod 1000000007
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
vector<vector<int> >pat[55];
vector<vector<int> >rec(int num){
	if(num <= 1){
		vector<vector<int> >ret;
		ret.pb(vector<int>());
		return ret;
	}
	if(pat[num].size()) return pat[num];
	pat[num].pb(vector<int>());
	for(int i=1;i<num;i++){
		vector<int>hoge;
		int zan = num;
		for(int j=i;(j == i || zan >= 2*i);j+=i){
			hoge.pb(j);
			zan -= i;
		}
		vector<vector<int> >pl = rec(zan);
		for(int j=0;j<pl.size();j++){
			vector<int>vi = hoge;
			for(int k=0;k<pl[j].size();k++) vi.pb(hoge[hoge.size()-1]+pl[j][k]);
			pat[num].pb(vi);
		}
	}
	return pat[num];
}
int s,t,n;
int dp[(1<<15)];
bitset<64>ok[(1<<15)];
struct UF{
	int par[55],ran[55];
	void init(){ for(int i=0;i<55;i++) par[i] = i; }
	int find(int x){ if(x == par[x]) return x; else return par[x] = find(par[x]); }
	void unite(int x,int y){
		x = find(x); y = find(y); if(x==y) return;
		if(ran[x] < ran[y]) par[x] = y;
		else{
			par[y] = x;
			if(ran[x] == ran[y]) ran[x]++;
		}
	}
	bool same(int x,int y){ return find(x)==find(y); }
}uf[(1<<15)];
bool cmp(const vector<int>& a,const vector<int>& b){
	return a.size() > b.size();
}
ll DP[205][2];
int main(){
	cin>>s>>t>>n;
	rec(t);
	sort(pat[t].begin(),pat[t].end(),cmp);
	for(int i=0;i<pat[t].size();i++){
		uf[i].init();
		for(int j=0;j<pat[t][i].size();j++){
			ok[i][pat[t][i][j]] = 1;
			int a = pat[t][i][j];
			assert(1<=a && a<t);
			for(int k=0;k+a<t;k++) uf[i].unite(k,k+a);
		}
		ll x = 1;
		for(int k=0;k<t;k++){
			if(uf[i].find(k) == k){
				x = x*1LL*n%mod;
			}
		}
		dp[i] = int(x);
		for(int j=0;j<i;j++){
			if((ok[j]&ok[i]) == ok[i]){
				dp[i] -= dp[j];
				if(dp[i] < 0) dp[i] += mod;
			}
		}
	}
	ll ans = 0;
	for(int i=0;i<pat[t].size();i++){
		for(int j=0;j<=s;j++) DP[j][0] = DP[j][1] = 0;
		DP[0][0] = 1;
		ll cur[2] = {};
		cur[0] = 1;
		ll res = 0;
		for(int j=1;j<=s-t+1;j++){
			for(int k=0;k<2;k++){
				DP[j][k] += cur[1-k];
				for(int a=0;a<pat[t][i].size();a++){
					if(j-pat[t][i][a] <= 0) break;
					DP[j][k] += DP[j-pat[t][i][a]][1-k];
				}
				DP[j][k] %= mod;
			}
			cur[0] = cur[0]*1LL*n%mod;
			cur[1] = cur[1]*1LL*n%mod;
			if(j>=t){
				cur[0] = (cur[0]+DP[j-t+1][0])%mod;
				cur[1] = (cur[1]+DP[j-t+1][1])%mod;
			}
		}
		ll tg = 1;
		for(int j=s-t+1;j>=1;j--){
			res += DP[j][1] * tg % mod;
			res -= DP[j][0] * tg % mod;
			tg = tg*1LL*n%mod;
		}
		res %= mod;
		ans += dp[i]*res%mod;
	}
	cout << (ans%mod+mod)%mod << endl;
}
accuracy: 0.15384615384615385
time_ms: 200
memory_kb: 16332
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll=int64_t;
#define int ll

#define FOR(i,a,b) for(int i=int(a);i<int(b);i++)
#define REP(i,b) FOR(i,0,b)
#define MP make_pair
#define PB push_back
#define ALL(x) x.begin(),x.end()
#define REACH cerr<<"reached line "<<__LINE__<<endl
#define DMP(x) cerr<<"line "<<__LINE__<<" "<<#x<<":"<<x<<endl
#define ZERO(x) memset(x,0,sizeof(x))

using pi=pair<int,int>;
using vi=vector<int>;
using ld=long double;

template<class T,class U>
ostream& operator<<(ostream& os,const pair<T,U>& p){
	os<<"("<<p.first<<","<<p.second<<")";
	return os;
}

template<class T>
ostream& operator <<(ostream& os,const vector<T>& v){
	os<<"[";
	REP(i,(int)v.size()){
		if(i)os<<",";
		os<<v[i];
	}
	os<<"]";
	return os;
}

int read(){
	int i;
	scanf("%" SCNd64,&i);
	return i;
}

void printSpace(){
	printf(" ");
}

void printEoln(){
	printf("\n");
}

void print(int x,int suc=1){
	printf("%" PRId64,x);
	if(suc==1)
		printEoln();
	if(suc==2)
		printSpace();
}

string readString(){
	static char buf[3341000];
	scanf("%s",buf);
	return string(buf);
}

char* readCharArray(){
	static char buf[3341000];
	static int bufUsed=0;
	char* ret=buf+bufUsed;
	scanf("%s",ret);
	bufUsed+=strlen(ret)+1;
	return ret;
}

template<class T,class U>
void chmax(T& a,U b){
	if(a<b)
		a=b;
}

template<class T,class U>
void chmin(T& a,U b){
	if(a>b)
		a=b;
}

template<class T>
T Sq(const T& t){
	return t*t;
}

const int inf=LLONG_MAX/3;

const int mod=1000000007;
template<class T,class U>
void add(T& a,U b){
	a=((ll)a+b)%mod;
}

template<class T,class U>
void sub(T& a,U b){
	a=((ll)a-b%mod+mod)%mod;
}

template<class T,class U>
void mult(T& a,U b){
	a=((ll)a*b)%mod;
}

ll modPow(ll a,ll p){
	ll s=1;
	while(p){
		if(p&1)mult(s,a);
		mult(a,a);
		p>>=1;
	}
	return s;
}

ll modInv(ll a){
	return modPow(a,mod-2);
}

const int Vmax=1000010;
int fact[Vmax],factInv[Vmax];
void InitFact(){
	fact[0]=1;
	FOR(i,1,Vmax){
		fact[i]=fact[i-1];
		mult(fact[i],i);
	}
	factInv[Vmax-1]=modInv(fact[Vmax-1]);
	for(int i=Vmax-2;i>=0;i--){
		factInv[i]=factInv[i+1];
		mult(factInv[i],i+1);
	}
}
int Choose(int n,int k){
	return fact[n]*factInv[n-k]%mod*factInv[k]%mod;
}

void gen(int len,int i,int a,vi&s,vector<vi>&dst){
	if(len==i)
		return void(dst.PB(s));
	REP(j,a){
		s.PB(j);
		gen(len,i+1,a,s,dst);
		s.pop_back();
	}
}
const int Nmax=210;
int n,m,a,ans,dp[Nmax],dq[Nmax],powBuf[Nmax];
void Init(){
	powBuf[0]=1;
	FOR(i,1,Nmax){
		powBuf[i]=powBuf[i-1];
		mult(powBuf[i],a);
	}
}
bool Check(const vi&s,const vi&t){
	int p=s.size(),q=t.size();
	REP(i,p-q+1){
		bool ok=true;
		REP(j,q)ok&=(s[i+j]==t[j]);
		if(ok)return true;
	}
	return false;
}
int GuChokudai(){
	vector<vi> ss,ts;
	vi tmp;
	gen(n,0,a,tmp,ss);
	gen(m,0,a,tmp,ts);
	int cnt=0;
	for(const auto&s:ss)for(const auto&t:ts)
		if(Check(s,t))cnt++;
	return cnt;
}
int Wafrelka(int d){
	ZERO(dp);
	ZERO(dq);
	FOR(i,m,n+1){
		dp[i]=modPow(a,i-m);
		REP(j,m)if((d>>j)&1LL)
			sub(dp[i],dp[i-m+j]);
		sub(dp[i],dq[i-m]);
		dq[i]=dp[i];
		add(dq[i],dq[i-1]*a);
	}
	return dq[n];
}
pi Futago(int d){
	assert(a==2);
	int cnt=0;
	REP(bit,1LL<<m){
		bool ok=true;
		FOR(i,1,m){
			int b=bit>>(m-i);
			bool same=(b==(bit&((1LL<<i)-1)));
			if(same!=((d>>i)&1))ok=false;
		}
		if(ok)
			cnt++;
	}
	return pi(cnt,Wafrelka(d));
}
void Tozan(int d){
	assert(a==2);
	REP(bit,1LL<<m){
		bool ok=true,ok2=false;
		FOR(i,1,m){
			int b=bit>>(m-i);
			bool same=(b==(bit&((1LL<<i)-1)));
			if(((d>>i)&1)&&!same)ok=false;
			if(((d>>i)&1)!=same)ok2=true;
		}
		if(ok&&ok2){
			vi arr(m);
			REP(i,m)arr[i]=(bit>>i)&1LL;
			cout<<arr<<endl;
		}
	}
}
vi divs,ways;
void rec(int len,int d,int w){
	if(len==m){
		int wtmp=w;
		REP(i,divs.size())
			if((d&divs[i])==d)
				sub(w,ways[i]);
		divs.PB(d);
		ways.PB(w);
		//pi ft=Futago(d);
		int wf=Wafrelka(d);
		/*if(ft!=pi(w,wf)){
			cerr<<d<<endl;
			cerr<<ft<<endl;
			cerr<<wtmp<<endl;
			cerr<<pi(w,wf)<<endl;
			cerr<<divs<<endl;
			cerr<<ways<<endl;
			//Tozan(d);
			assert(false);
		}*/
		add(ans,wf*w);
		//ans++;
		return;
	}
	FOR(e,len+1,m+1){
		int f=d|(1LL<<e);
		int g=w;
		if(e>=len*2){
			mult(g,powBuf[e-len*2]);
			rec(e,f,g);
		}else if((d>>(len*2-e))&1){
			rec(e,f,g);
		}
	}
	/*FOR(i,1,len){
		int e=len,f=d;
		while(e-1>=i){
			f|=(1LL<<e);
			e-=i;
		}
		int g=w;
		mult(g,modPow(a,i-e));
		rec(e,f,g);
	}
	{
		int e=0,f=d|(1LL<<len);
		int g=w;
		mult(g,modPow(a,len));
		rec(e,f,g);
	}*/
}

signed main(){
	n=read(),m=read(),a=read();
	Init();
	rec(0,0,1);
	cout<<ans<<endl;
	//cout<<GuChokudai()<<endl;
	/*{
		assert(m==1);
		int w=modPow(a,n);
		sub(w,modPow(a-1,n));
		mult(w,a);
		cout<<w<<endl;
	}*/
	/*{
		assert(n==m);
		cout<<modPow(a,n)<<endl;
	}*/
}
accuracy: 1
time_ms: 310
memory_kb: 3340
final_rank: 6

code_snippet: #define _USE_MATH_DEFINES
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <cfloat>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
typedef pair<int, ll> i_ll;
struct edge { int u, v; ll w; };

ll INF = LLONG_MAX / 2;
ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;

struct union_find {
	vector<int> v;
	union_find(int n) : v(n, -1) {}
	int find(int x) { return v[x] < 0 ? x : v[x] = find(v[x]); }
	void unite(int x, int y) {
		x = find(x); y = find(y);
		if (x == y) return;
		if (x > y) swap(x, y);
		v[x] += v[y]; v[y] = x;
	}
	bool root(int x) { return v[x] < 0; }
	bool same(int x, int y) { return find(x) == find(y); }
	int size(int x) { return -v[find(x)]; }
};

ll pow_mod(ll x, ll n, int M) {
	ll ans = 1;
	for (; n; n>>=1) {
		if (n & 1) ans = ans * x % M;
		x = x * x % M;
	}
	return ans;
}

map<vector<int>, int> mp[200];

int main() {
	int N, M, A; cin >> N >> M >> A;
	union_find a(M);
	int ans = 0;
	for (int i = 0; i + M <= N; i++) {
		mp[i][a.v] = (mp[i][a.v] + pow_mod(A, i, MOD)) % MOD;
		for (auto p: mp[i]) {
			vector<int> a = p.first;
			int x = p.second, z = x;
			for (int j = 0; j < M; j++)
				if (a[j] < 0)
					z = (ll)z * A % MOD;
			ans = (ans + z * pow_mod(A, N - (i + M), MOD)) % MOD;
			for (int d = 1; i + d + M <= N; d++)
				if (d <= M - 1) {
					union_find uf(M); uf.v = a;
					for (int j = 0; j + d < M; j++)
						uf.unite(j, j + d);
					for (int j = 0; j < M; j++)
						uf.find(j);
					int& _x = mp[i + d][uf.v];
					_x = (_x - x) % MOD;
				}
				else {
					int& _x = mp[i + d][a];
					_x = (_x - x * pow_mod(A, d - M, MOD)) % MOD;
				}
		}
	}
	cout << (ans + MOD) % MOD << endl;
}
accuracy: 1
time_ms: 1400
memory_kb: 29120
final_rank: 10

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){return o<<"("<<p.fs<<","<<p.sc<<")";}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){o<<"sz = "<<vc.size()<<endl<<"[";for(const T& v:vc) o<<v<<",";o<<"]";return o;}
struct UnionFind{
	int par[51];
	void init(int N){rep(i,N) par[i]=i;}
	int find(int x){
		if(x==par[x]) return x;
		return par[x]=find(par[x]);
	}
	bool same(int x,int y){return find(x)==find(y);}
	void unite(int x,int y){
		x=find(x),y=find(y);
		par[x]=y;
	}
}UF;
typedef long long ll;
ll N,M,A,n[2249],mod=1e9+7;
ll dp[200][200];
void add(ll &x,ll y){
	x+=y;
	x%=mod;
}
inline ll B(int x){return 1LL<<x;}
bool B(ll x,int i){return (x>>i)&1;}
bool is_pset(ll b){
	UF.init(M);
	rep(i,M) if((b>>i)&1){
		rep(j,M-i) UF.unite(j,j+i);
	}
	ll x=0;
	rep1(i,M-1){
		bool ok=1;
		rep(j,M-i) if(!UF.same(j,j+i)) ok=0;
		if(ok) x|=B(i);
	}
	return b==x;
}
int dim(ll b){
	UF.init(M);
	rep(i,M) if((b>>i)&1){
		rep(j,M-i) UF.unite(j,j+i);
	}
	int d=0;
	rep(i,M) if(i==UF.find(i)) d++;
	return d;
}
vector<ll> vc;
void enum_pset(int L,ll b){
	if(L==0){
		if(is_pset(b)) vc.pb(b);
		return;
	}
	rep1(p,L){
		if(p<=L/2){
			ll nb=b;
			for(int k=p;k<L;k+=p) nb|=B(k+M-L);
			enum_pset(L%p+p,nb);
		}else{
			ll nb=b;
			for(int k=p;k<L;k+=p) nb|=B(k+M-L);
			enum_pset(L-p,nb);
		}
	}
}
ll calc(ll x){
	rep(i,N) rep(j,N) dp[i][j]=0;
	dp[0][0]=1;
	rep(i,N-M) dp[i+1][i+1]=dp[i][i]*A%mod;

	rep(i,N-1) rep(j,N) if(dp[i][j]!=0){
		if(i+1+M<=N && (i+1>=j+M || B(x,i+1-j)) ){
			add(dp[i+1][i+1],-dp[i][j]);
		}
		if(i+1>=j+M) add(dp[i+1][j],dp[i][j]*A);
		else add(dp[i+1][j],dp[i][j]);
	}
	ll ret=0;
	rep(j,N) add(ret,dp[N-1][j]);
	return ret;
}

int main(){
	cin>>N>>M>>A;
	enum_pset(M,0);
	sort(all(vc));
	vc.erase(unique(vc.begin(),vc.end()),vc.end());
	int K=vc.size();
	reverse(all(vc));
	rep(i,K){
		int d=dim(vc[i]);
		n[i]=1;
		rep(j,d) n[i]=n[i]*A%mod;
	}
	ll ans=0;
	rep(i,K){
		ll tmp=calc(vc[i]);
		rep(j,i) if((vc[i]&vc[j])==vc[i]) add(n[i],-n[j]);
		add(ans,n[i]*tmp);
	}
	cout<<(ans+mod)%mod<<endl;
}
accuracy: 1
time_ms: 560
memory_kb: 3528
final_rank: 7

code_snippet: #include<cstdio>
#include<vector>
#include<algorithm>

using namespace std;

const long long mod = 1000000007;

struct UnionFind{
	vector<int> par;
	void init(int N){
		par.clear();
		for(int i = 0; i < N; ++i){
			par.push_back(i);
		}
	}
	int find(int x){
		if(x == par[x]) return x;
		return par[x] = find(par[x]);
	}
	void unite(int x, int y){
		x = find(x), y = find(y);
		if(x == y) return;
		par[x] = y;
	}
	bool same(int x, int y){
		return find(x) == find(y);
	}
};

long long pw[220];

vector<long long> valid_cycles;
vector<long long> num_t;

int N, M, A;

void dfs(int c, UnionFind uf, long long st){
	if(c == M){
		for(int c2 = 1; c2 < M; ++c2){
			if(((st >> c2) & 1) == 0){
				bool flg = false;
				for(int i = 0; i + c2 < M; ++i){
					bool tmp = uf.same(i, i + c2);
					if(!tmp){
						flg = true;
						break;
					}
				}
				if(!flg) return;
			}
		}
		valid_cycles.push_back(st);
		int cnt = 0;
		for(int i = 0; i < M; ++i){
			if(uf.find(i) == i) cnt++;
		}
		num_t.push_back(pw[cnt]);
		return;
	}
	//c is not a period
	bool flg = false;
	for(int i = 0; i + c < M; ++i){
		bool tmp = uf.same(i, i + c);
		if(!tmp){
			flg = true;
			break;
		}
	}
	if(flg){
		dfs(c + 1, uf, st);
	}
	//c is a period
	for(int i = 0; i + c < M; ++i){
		uf.unite(i, i + c);
	}
	dfs(c + 1, uf, st | (1ll << c));
}

long long dp[220];

long long count_s(long long cycles){
	for(int i = 0; i < 220; ++i) dp[i] = 0;
	for(int i = M; i <= N; ++i){
		dp[i] = pw[i - M];
		for(int j = M; j <= i - M; ++j){
			long long coe1 = dp[j];
			long long coe2 = pw[i - M - j];
			dp[i] = (dp[i] - coe1 * coe2) % mod;
		}
		for(int j = i - M + 1; j < i; ++j){
			int d = i - j;
			if((cycles >> d) & 1){
				dp[i] = (dp[i] - dp[j]) % mod;
			}
		}
	}
	long long res = 0;
	for(int i = M; i <= N; ++i){
		long long coe1 = dp[i];
		long long coe2 = pw[N - i];
		res = (res + coe1 * coe2) % mod;
	}
	res += mod;
	res %= mod;
	return res;
}

void count_t(){
	for(int i = (int)valid_cycles.size() - 1; i >= 0; --i){
		for(int j = i + 1; j < valid_cycles.size(); ++j){
			if((valid_cycles[i] & valid_cycles[j]) == valid_cycles[i]){
				num_t[i] = (num_t[i] - num_t[j]) % mod;
			}
		}
	}
}

long long solve(){
	pw[0] = 1;
	for(int i = 1; i < 220; ++i) pw[i] = (pw[i - 1] * A) % mod;
	UnionFind uf;
	uf.init(M);
	dfs(1, uf, 0);
	count_t();
	long long ans = 0;
	for(int i = 0; i < valid_cycles.size(); ++i){
		long long num1 = num_t[i];
		long long num2 = count_s(valid_cycles[i]);
		ans = (ans + num1 * num2) % mod;
	}
	ans += mod;
	ans %= mod;
	return ans;
}

int main(){
	scanf("%d%d%d", &N, &M, &A);
	long long ans = solve();
	printf("%lld\n", ans);
	return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 1156
final_rank: 1

code_snippet: #include <cstdio>
#include <cstdlib>

int eq[52];
int dsu[52];
int n;
int ways[2300][52], _[2300];
long long bit[2300];
int cnt;

int find(int x){return x == dsu[x] ? x : dsu[x] = find(dsu[x]);}

void dfs(int i, long long b){
  int j, k;
  int _dsu[52] = {};
  
  for (j = 1; j < i; j++)
    if (eq[j] == 0){
      for (k = 1; k <= j; k++)
	if (find(k) != find(n - j + k)) break;
      if (k > j) return;
    }

  if (i == n){
    cnt++;
    for (j = 1; j <= n; j++){
      ways[cnt][j] = eq[j];
      _[cnt] += (dsu[j] == j);
      bit[cnt] = b;
    }
    return;
  }

  for (j = 1; j <= n; j++) _dsu[j] = dsu[j];
  dfs(i + 1, b);
  eq[i] = 1;
  for (j = 1; j <= i; j++) dsu[find(j)] = find(n - i + j);
  dfs(i + 1, b | (1ll << i));
  for (j = 1; j <= n; j++) dsu[j] = _dsu[j];
  eq[i] = 0;
}

void prepare(){
  for (int i = 1; i <= n; i++) dsu[i] = i;
  dfs(1, 0);
}

const int ljz = 1000000007;
int Tm(int x, int y){long long a = x, b = y; return (a * b) % ljz;}
void MOD(int &x){if (x >= ljz) x -= ljz; if (x < 0) x += ljz;}

int m, a;
int pw[2322], gtf[2322];
int f[221][2];
int ans;
int G[2322];

void doit(int *w, int bh){
  int i, j, k;
  for (i = 1; i <= m + 1; i++) f[i][0] = f[i][1] = 0;
  for (i = 1; i <= m - n + 1; i++) f[i][1] = pw[i - 1];
  for (i = 1; i <= m - n + 1; i++)
    for (k = 0; k < 2; k++)
      if (f[i][k])
	for (j = i + 1; j <= m - n + 1; j++){
	  if (j - i < n){
	    if (w[n + i - j])
	      MOD(f[j][k ^ 1] += f[i][k]);
	  } else
	    MOD(f[j][k ^ 1] += Tm(f[i][k], pw[j - i - n]));
	}
  for (i = 1; i <= m - n + 1; i++){
    int q; MOD(q = f[i][1] - f[i][0]);
    MOD(ans += Tm(q, Tm(G[bh], pw[m - i - n + 1])));
  }
}

int main(){
  int i, j;
  scanf("%d %d %d", &m, &n, &a);
  for (i = pw[0] = 1; i <= m; i++) pw[i] = Tm(pw[i - 1], a);
  prepare();
  ans = 0;
  for (i = cnt; i; i--){
    G[i] = pw[_[i]];
    for (j = cnt; j > i; j--)
      if ((bit[i] & bit[j]) == bit[i])
	MOD(G[i] -= G[j]);
  }
  for (i = 1; i <= cnt; i++) doit(ways[i], i);
  printf("%d\n", ans);
  return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 1544
final_rank: 3