C. Constanze's Machine

https://codeforces.com/problemset/problem/1245/C

题意:给定一个字符串s,字符串中连续的"nn"和"uu"可能由m和w变换而来,但也可能不是。问有多少种字符串是合法的?字符串如果包含任意的m和n则不合法。

思路:动态规划,依次考虑第i个位置的字符,如果i和i-1的字符是nn或者uu,那么dp[i] += dp[i - 2];

总结:字符串下标从0开始,dp下标从1开始~~ 因为有了模板,取模都不用管了,真好用啊

#include <bits/stdc++.h>


#define dbg std::cout << "----------------------------------------" << std::endl;


constexpr const std::array<int, 4> dx  { -1, 1, 0, 0 };
constexpr const std::array<int, 4> dy  { 0, 0, -1, 1 };
constexpr const std::array<int, 8> dx2 { -1, -1, 0, 1, 1, 1, 0, -1 };
constexpr const std::array<int, 8> dy2 { 0, -1, -1, -1, 0, 1, 1, 1 };

constexpr const int         INF      =  0x3f3f3f3f;         /*  1e9 */
constexpr const long long   INF_LL   =  0x3f3f3f3f3f3f3f3f; /* 4e18 */

template<typename T, typename U>
inline typename std::common_type<T, U>::type gcd(T a, U b) {
    typename std::common_type<T, U>::type t;
    while (b != 0) {
        t = a % b;
        a = b;
        b = t;
    }
    return a;
}
inline long long lcm(long long a, long long b) { return a / ::gcd(a, b) * b; }

template<typename T, typename U>
inline bool checkMax(T& a, const U& b) { return a < b ? a = b, true : false; }
template<typename T, typename U>
inline bool checkMin(T& a, const U& b) { return a > b ? a = b, true : false; }

inline int ppc  (int x)           { return __builtin_popcount(x); }
inline int ctz  (int x)           { return __builtin_ctz(x); }
inline int ppcll(long long x)     { return __builtin_popcountll(x); }
inline int ctzll(long long x)     { return __builtin_ctzll(x); }

// template<typename T, typename U>
// inline T extendEuclid(T a, U b, int &x, int &y) {
//     x = 1, y = 0;
//     int x1 = 0, y1 = 1, a1 = a, b1 = b;
//     while (b1) {
//         int q = a1 / b1;
//         std::tie(x, x1) = std::make_tuple(x1, x - q * x1);
//         std::tie(y, y1) = std::make_tuple(y1, y - q * y1);
//         std::tie(a1, b1) = std::make_tuple(b1, a1 - q * b1);
//     }
//     return a1;
// }

/*
* ModInt(自动进行模运算的数据类型)
* 设计思想:参考自tourist
* 基于面向对象的编程思想,本方法尽可能多的隐藏了内部实现的细节,并且将必要的编程接口暴露在外部,并需要对这些接口进行直接的修改。
* 
*                             使用方法: 将MInt作为基本数据类型来使用即可,无需考虑模除法运算与运算溢出。
*                                      将本文底部mod值改为需要使用的模数即可。
*                             幂运算:幂运算基于ModInt类中的静态函数MInt::power(MInt a, type b);
*                             注意事项:类内求逆元使用的是拓展欧几里得,如有需要可自行改成费马小定理。
*
* gitHub(仓库地址): https://github.com/yxc-s/programming-template.git











*///TODO:增加更多的运算符重载
template<typename T, typename U, typename V>
inline T fastPower(T a, U b, const V& mod) {
    assert(b >= 0);
    T res = 1;
    for (; b > 0; a = 1ll * a * a % mod, b >>= 1) {
        if (b & 1) {
            res = 1ll * res * a % mod;
        }
    }
    return res;
}

template<typename T, typename U>
inline T fermatInverse(const T& a, const U& mod) { return fastPower(a, mod - 2, mod); }


template <typename T, typename U>
inline T extendEuclidInverse(T a, U mod) {
    T x = 0, y = 1;
    while (a != 0) {
        T q = mod / a;
        mod -= q * a; std::swap(a, mod);
        x -= q * y; std::swap(x, y);
    }
    assert(mod == 1);
    return x;
}

template<typename T>
class ModInt {
public:
    using Type = typename std::decay<decltype(T::value)>::type;
    ModInt(long long value = 0) : value_(normalize(value)) {}
    ModInt(const ModInt<T>& other) = default;
    ModInt(ModInt<T>&& other) : value_(other.value_) {}
    ~ModInt() = default;


    ModInt& operator += (const ModInt& other) { return value_ = normalize(value_ + other.value_), *this; }
    ModInt& operator -= (const ModInt& other) { return value_ = normalize(value_ - other.value_), *this; }
    ModInt& operator ++ () { return normalize(++value_), *this; }
    ModInt& operator -- () { return normalize(--value_), *this; }
    ModInt  operator ++ (int) { ModInt res{ *this }; return *this += 1, res; }
    ModInt  operator -- (int) { ModInt res(*this); return *this -= 1, res; }
    template<typename U> ModInt& operator += (const U& other) { return *this += ModInt(other); }
    template<typename U> ModInt& operator -= (const U& other) { return *this -= ModInt(other); }

    ModInt& operator =(const ModInt& other) {
        if (this != &other) {
            value_ = other.value_;
        }
        return *this;
    }

    template<typename U, typename = std::enable_if_t<std::is_integral_v<U>>>
    ModInt& operator =(U x) {
        value_ = normalize(x);
        return *this;
    }

    template <typename U = T>
    typename std::enable_if<std::is_same<typename ModInt<U>::Type, int>::value, ModInt>::type& operator *= (const ModInt& other) {
        value_ = normalize(static_cast<long long>(value_) * static_cast<long long>(other.value_));
        return *this;
    }

    template <typename U = T>
    typename std::enable_if<std::is_same<typename ModInt<U>::Type, long long>::value, ModInt>::type& operator *= (const ModInt& other) {
        long long q = static_cast<long long>(static_cast<long double>(value_) * other.value_ / getModValue());
        value_ = normalize(value_ * other.value - q * getModValue());
        return *this;
    }

    ModInt& operator /= (const ModInt& other) {
        //return *this *= ModInt(fermatInverse(other.value_, getModValue()));/*Fermat Inverse requires a prime Mod value!!*/
        return *this *= ModInt(extendEuclidInverse(other.value_, getModValue()));
    }

    template<typename U>
    friend bool operator == (const ModInt<U>& lhs, const ModInt<U>& rhs);

    template <typename U>
    friend bool operator < (const ModInt<U>& lhs, const ModInt<U>& rhs);

    template<typename U>
    friend std::ostream& operator << (std::ostream& os, const ModInt<U>& number) {
        os << number.value_;
        return os;
    }

    template<typename U>
    friend std::istream& operator >> (std::istream& is, ModInt<U>& number) {
        typename std::common_type<typename ModInt<U>::Type, long long>::type value;
        is >> value;
        number.value_ = normalize(value);
        return is;
    }

    template<typename U>
    static Type normalize(const U& value) {
        Type res = static_cast<Type> (value % getModValue());
        res = (res < 0 ? res + getModValue() : res > getModValue() ? res - getModValue() : res);
        return res;
    }

    /* 获取原本元素值,或者转为整形 */
    Type operator () () const { return this->value_; }
    operator int() const noexcept{ return static_cast<int>(value_); }
    operator long long() const noexcept { return static_cast<long long> (value_); }

    template<typename U, typename V>
    static U power(U a, V b) {
        assert(b >= 0);
        U res = 1;
        for (; b > 0; a = a * a, b >>= 1) {
            if (b & 1) {
                res = res * a;
            }
        }
        return res;
    }

    ModInt power(long long b) const noexcept { return ModInt::power(*this, b); }



private:
    Type value_;
    constexpr static Type getModValue() { return T::value; }

};

template <typename T>             bool operator == (const ModInt<T>& lhs, const ModInt<T>& rhs) { return lhs.value_ == rhs.value_; }
template <typename T, typename U> bool operator == (const ModInt<T>& lhs, U rhs) { return lhs == ModInt<T>(rhs); }
template <typename T, typename U> bool operator == (U lhs, const ModInt<T>& rhs) { return ModInt<T>(lhs) == rhs; }

template <typename T>             bool operator != (const ModInt<T>& lhs, const ModInt<T>& rhs) { return !(lhs == rhs); }
template <typename T, typename U> bool operator != (const ModInt<T>& lhs, U rhs) { return !(lhs == rhs); }
template <typename T, typename U> bool operator != (U lhs, const ModInt<T>& rhs) { return !(lhs == rhs); }

template <typename T> ModInt<T>             operator + (const ModInt<T>& lhs, const ModInt<T>& rhs) { return ModInt<T>(lhs) += rhs; }
template <typename T, typename U> ModInt<T> operator + (const ModInt<T>& lhs, U rhs) { return ModInt<T>(lhs) += rhs; }
template <typename T, typename U> ModInt<T> operator + (U lhs, const ModInt<T>& rhs) { return ModInt<T>(lhs) += rhs; }

template <typename T>             ModInt<T> operator - (const ModInt<T>& lhs, const ModInt<T>& rhs) { return ModInt<T>(lhs) -= rhs; }
template <typename T, typename U> ModInt<T> operator - (const ModInt<T>& lhs, U rhs) { return ModInt<T>(lhs) -= rhs; }
template <typename T, typename U> ModInt<T> operator - (U lhs, const ModInt<T>& rhs) { return ModInt<T>(lhs) -= rhs; }

template <typename T>             ModInt<T> operator * (const ModInt<T>& lhs, const ModInt<T>& rhs) { return ModInt<T>(lhs) *= rhs; }
template <typename T, typename U> ModInt<T> operator * (const ModInt<T>& lhs, U rhs) { return ModInt<T>(lhs) *= rhs; }
template <typename T, typename U> ModInt<T> operator * (U lhs, const ModInt<T>& rhs) { return ModInt<T>(lhs) *= rhs; }

template <typename T>             ModInt<T> operator / (const ModInt<T>& lhs, const ModInt<T>& rhs) { return ModInt<T>(lhs) /= rhs; }
template <typename T, typename U> ModInt<T> operator / (const ModInt<T>& lhs, U rhs) { return ModInt<T>(lhs) /= rhs; }
template <typename T, typename U> ModInt<T> operator / (U lhs, const ModInt<T>& rhs) { return ModInt<T>(lhs) /= rhs; }

template <typename T> bool operator < (const ModInt<T>& lhs, const ModInt<T>& rhs) { return lhs.value_ < rhs.value_; }

constexpr int mod = (int)(1e9 + 7);
using MInt = ModInt<std::integral_constant<std::decay<decltype(mod)>::type, mod>>;

/*

*/
using namespace std;


inline void preProcess() {

}



inline void solve(){
    string s;
    cin >> s;

    for (auto& x : s) {
        if (x == 'm' || x == 'w') {
            cout << 0;
            return;
        }
    }
    int n = (int)s.size();

    vector<MInt> dp(n + 1);
    dp[0] = dp[1] = 1;
    for (int i = 2; i <= n; ++i) {
        dp[i] = dp[i - 1];
        if (s[i - 1] == s[i - 2] && (s[i - 1] == 'u' || s[i - 1] == 'n')) {
            dp[i] += dp[i - 2];
        }
    }

    cout << dp[n];
}

int main() {
    std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
    int tc = 1;

    preProcess();

    if constexpr (0){
        cin >> tc;
    }

    while (tc--) {
        solve();
    }

#ifdef LOCAL_DEBUG
    std::cout << std::endl;
#endif

    return 0;
}
posted @ 2025-03-07 13:40  _Yxc  阅读(10)  评论(0)    收藏  举报