結果
問題 | No.1502 Many Simple Additions |
ユーザー |
|
提出日時 | 2021-05-09 21:00:39 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 11,692 bytes |
コンパイル時間 | 2,329 ms |
コンパイル使用メモリ | 187,772 KB |
実行使用メモリ | 20,736 KB |
最終ジャッジ日時 | 2024-09-19 01:50:31 |
合計ジャッジ時間 | 6,579 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 5 |
other | AC * 22 WA * 17 |
ソースコード
/*** author: ivanzuki* created: Sat May 08 2021**/#include <bits/stdc++.h>using namespace std;string to_string(string s) {return '"' + s + '"';}string to_string(const char* s) {return to_string((string) s);}string to_string(bool b) {return (b ? "true" : "false");}template <typename A, typename B>string to_string(pair<A, B> p) {return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";}template <typename A>string to_string(A v) {bool first = true;string res = "{";for (const auto &x : v) {if (!first) {res += ", ";}first = false;res += to_string(x);}res += "}";return res;}void debug_out() { cerr << endl; }template <typename Head, typename... Tail>void debug_out(Head H, Tail... T) {cerr << " " << to_string(H);debug_out(T...);}template<typename T> void dout(string name, int idx, T arg) {cerr << name << " = " << to_string(arg);}template<typename T1, typename... T2> void dout(string names, int idx, T1 arg, T2... args) {cerr << names.substr(0, names.find(',')) << " = " << to_string(arg) << ", ";dout(names.substr(names.find(',') + 2), idx + 1, args...);}#ifdef LOCAL#define debug(...) cerr << "[", dout(#__VA_ARGS__, 0, __VA_ARGS__), cerr << "]" << endl;#else#define debug(...) 42#endiftemplate <typename T>T inverse(T a, T m) {T u = 0, v = 1;while (a != 0) {T t = m / a;m -= t * a; swap(a, m);u -= t * v; swap(u, v);}assert(m == 1);return u;}template <typename T>class Modular {public:using Type = typename decay<decltype(T::value)>::type;constexpr Modular() : value() {}template <typename U>Modular(const U& x) {value = normalize(x);}template <typename U>static Type normalize(const U& x) {Type v;if (-mod() <= x && x < mod()) v = static_cast<Type>(x);else v = static_cast<Type>(x % mod());if (v < 0) v += mod();return v;}const Type& operator()() const { return value; }template <typename U>explicit operator U() const { return static_cast<U>(value); }constexpr static Type mod() { return T::value; }Modular& operator+=(const Modular& other) { if ((value += other.value) >= mod()) value -= mod(); return *this; }Modular& operator-=(const Modular& other) { if ((value -= other.value) < 0) value += mod(); return *this; }template <typename U> Modular& operator+=(const U& other) { return *this += Modular(other); }template <typename U> Modular& operator-=(const U& other) { return *this -= Modular(other); }Modular& operator++() { return *this += 1; }Modular& operator--() { return *this -= 1; }Modular operator++(int) { Modular result(*this); *this += 1; return result; }Modular operator--(int) { Modular result(*this); *this -= 1; return result; }Modular operator-() const { return Modular(-value); }template <typename U = T>typename enable_if<is_same<typename Modular<U>::Type, int>::value, Modular>::type& operator*=(const Modular& rhs) {#ifdef _WIN32uint64_t x = static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value);uint32_t xh = static_cast<uint32_t>(x >> 32), xl = static_cast<uint32_t>(x), d, m;asm("divl %4; \n\t": "=a" (d), "=d" (m): "d" (xh), "a" (xl), "r" (mod()));value = m;#elsevalue = normalize(static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value));#endifreturn *this;}template <typename U = T>typename enable_if<is_same<typename Modular<U>::Type, int64_t>::value, Modular>::type& operator*=(const Modular& rhs) {int64_t q = static_cast<int64_t>(static_cast<long double>(value) * rhs.value / mod());value = normalize(value * rhs.value - q * mod());return *this;}template <typename U = T>typename enable_if<!is_integral<typename Modular<U>::Type>::value, Modular>::type& operator*=(const Modular& rhs) {value = normalize(value * rhs.value);return *this;}Modular& operator/=(const Modular& other) { return *this *= Modular(inverse(other.value, mod())); }template <typename U>friend const Modular<U>& abs(const Modular<U>& v) { return v; }template <typename U>friend bool operator==(const Modular<U>& lhs, const Modular<U>& rhs);template <typename U>friend bool operator<(const Modular<U>& lhs, const Modular<U>& rhs);template <typename U>friend std::istream& operator>>(std::istream& stream, Modular<U>& number);private:Type value;};template <typename T> bool operator==(const Modular<T>& lhs, const Modular<T>& rhs) { return lhs.value == rhs.value; }template <typename T, typename U> bool operator==(const Modular<T>& lhs, U rhs) { return lhs == Modular<T>(rhs); }template <typename T, typename U> bool operator==(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) == rhs; }template <typename T> bool operator!=(const Modular<T>& lhs, const Modular<T>& rhs) { return !(lhs == rhs); }template <typename T, typename U> bool operator!=(const Modular<T>& lhs, U rhs) { return !(lhs == rhs); }template <typename T, typename U> bool operator!=(U lhs, const Modular<T>& rhs) { return !(lhs == rhs); }template <typename T> bool operator<(const Modular<T>& lhs, const Modular<T>& rhs) { return lhs.value < rhs.value; }template <typename T> Modular<T> operator+(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) += rhs; }template <typename T, typename U> Modular<T> operator+(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) += rhs; }template <typename T, typename U> Modular<T> operator+(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) += rhs; }template <typename T> Modular<T> operator-(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) -= rhs; }template <typename T, typename U> Modular<T> operator-(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) -= rhs; }template <typename T, typename U> Modular<T> operator-(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) -= rhs; }template <typename T> Modular<T> operator*(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) *= rhs; }template <typename T, typename U> Modular<T> operator*(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) *= rhs; }template <typename T, typename U> Modular<T> operator*(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) *= rhs; }template <typename T> Modular<T> operator/(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) /= rhs; }template <typename T, typename U> Modular<T> operator/(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) /= rhs; }template <typename T, typename U> Modular<T> operator/(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) /= rhs; }template<typename T, typename U>Modular<T> power(const Modular<T>& a, const U& b) {assert(b >= 0);Modular<T> x = a, res = 1;U p = b;while (p > 0) {if (p & 1) res *= x;x *= x;p >>= 1;}return res;}template <typename T>bool IsZero(const Modular<T>& number) {return number() == 0;}template <typename T>string to_string(const Modular<T>& number) {return to_string(number());}template <typename T>std::ostream& operator<<(std::ostream& stream, const Modular<T>& number) {return stream << number();}template <typename T>std::istream& operator>>(std::istream& stream, Modular<T>& number) {typename common_type<typename Modular<T>::Type, int64_t>::type x;stream >> x;number.value = Modular<T>::normalize(x);return stream;}/*using ModType = int;struct VarMod { static ModType value; };ModType VarMod::value;ModType& md = VarMod::value;using Mint = Modular<VarMod>;*/constexpr int md = (int) 1e9 + 7;using Mint = Modular<std::integral_constant<decay<decltype(md)>::type, md>>;const int inf = (int) 1e9;int main() {ios_base::sync_with_stdio(false);cin.tie(0);int n, m, k;cin >> n >> m >> k;vector<vector<pair<int, int>>> g(n);for (int i = 0; i < m; i++) {int x, y, z;cin >> x >> y >> z;--x; --y;g[x].emplace_back(y, z);g[y].emplace_back(x, z);}vector<int> was(n);vector<int> value(n, -1);vector<int> depth(n);int cc = 0;vector<int> can(n, 1);vector<int> l(n, -inf), r(n, inf);vector<Mint> all_ways(n), inner_ways(n);vector<set<int>> needs(n);function<void(int)> DFS = [&](int v) {was[v] = 1;if (depth[v] % 2 == 0) {if (value[v] > k) {can[cc] = 0;} else {l[cc] = max(l[cc], -value[v] + 1);r[cc] = min(r[cc], k - value[v]);}} else {if (value[v] >= k) {l[cc] = max(l[cc], value[v] - k);}r[cc] = min(r[cc], value[v] - 1);}for (const auto& e : g[v]) {int u = e.first, w = e.second;if (was[u] == 0) {value[u] = w - value[v];depth[u] = depth[v] + 1;DFS(u);} else {if (depth[v] % 2 == depth[u] % 2) {if (abs(w - (value[v] + value[u])) % 2 == 0) {if (depth[v] % 2 == 0) {int need = (w - (value[v] + value[u])) / 2;if (need < 0) {can[cc] = 0;} else {needs[cc].insert(need);}} else {int need = ((value[v] + value[u]) - w) / 2;if (need < 0) {can[cc] = 0;} else {needs[cc].insert(need);}}} else {can[cc] = 0;}} else {if (value[v] + value[u] != w) {can[cc] = 0;}}}}};Mint ans = 1;vector<int> value_k(n);vector<int> was_k(n);function<int(int)> TheMax = [&](int v) {was_k[v] = 1;int ret = value_k[v];for (const auto& e : g[v]) {int u = e.first, w = e.second;value_k[u] = w - value_k[v];if (!was_k[u]) {ret = max(ret, TheMax(u));}}return ret;};for (int i = 0; i < n; i++) {if (was[i] == 0) {value[i] = 1;DFS(i);if (!can[cc]) {ans = 0;} else {auto Doable = [&](const set<int>& needs) {int last = -1;for (const auto& t : needs) {if (t != l[cc] && t != r[cc]) {return false;}if (last != -1) {if (t != last) {return false;}}last = t;}return true;};if (l[cc] > r[cc] || l[cc] < 0 || !Doable(needs[cc])) {can[cc] = 0;} else {value_k[i] = l[cc] + 1;// all_ways[cc] = 1 + (l[cc] < r[cc]);// debug(TheMax(i));bool left = (TheMax(i) == k && (needs[cc].empty() || *needs[cc].begin() == l[cc]));debug(all_ways[cc]);value_k[i] = r[cc] + 1;fill(was_k.begin(), was_k.end(), 0);// debug(TheMax(i));bool right = (l[cc] < r[cc] && TheMax(i) == k && (needs[cc].empty() || *needs[cc].begin() == r[cc]));debug(all_ways[cc]);all_ways[cc] = left + right;inner_ways[cc] = max(0, r[cc] - l[cc] - 1 + !left + !right);}ans *= (all_ways[cc] + inner_ways[cc]);}++cc;}}if (ans == 0) {debug(ans, l, r, cc, all_ways, inner_ways, can, needs);cout << ans << '\n';} else {Mint remove = 1;for (int i = 0; i < cc; i++) {remove *= inner_ways[i];}debug(ans, remove, l, r, cc, all_ways, inner_ways, needs);ans -= remove;cout << ans << '\n';}return 0;}