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;
}

浙公网安备 33010602011771号