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_DEBUGstd::cout << std::endl;
#endifreturn 0;
}