Submission #1264324

#TimeUsernameProblemLanguageResultExecution timeMemory
1264324trufanov.pFancy Fence (CEOI20_fancyfence)C++20
100 / 100
51 ms4316 KiB
#include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <cctype> #include <string> #include <queue> #include <unordered_set> #include <deque> #include <numeric> #include <cmath> #include <unordered_map> #include <set> #include <stack> using namespace std; #pragma GCC optimize("O3") #pragma GCC optimization("Ofast,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") typedef long long ll; template <int Mod> class ModInt { private: int x; int __add(int a, int b) const { return (a + b < Mod ? a + b : a + b - Mod); } int __sub(int a, int b) const { return __add(a - b, Mod); } int __mul(int a, int b) const { ll a_ = a, b_ = b, Mod_ = Mod; return static_cast<int>((a_ * b_) % Mod_); } int __pow(int a, int b) const { int res = 1; int pw = a; while (b) { if (b & 1) { res = __mul(res, pw); } pw = __mul(pw, pw); b /= 2; } return res; } int __inv(int a) const { return __pow(a, Mod - 2); } int __div(int a, int b) const { return __mul(a, __inv(b)); } public: ModInt() :x(0) {} template <typename U, std::enable_if_t<std::is_convertible_v<U, int>, int> = 0> ModInt(U x_) : x(static_cast<int>(x_)) {} ModInt operator +(const ModInt& other) const { return ModInt(__add(x, other.x)); } ModInt& operator +=(const ModInt& other) { x = __add(x, other.x); return *this; } ModInt operator -(const ModInt& other) const { return ModInt(__sub(x, other.x)); } ModInt& operator -=(const ModInt& other) { x = __sub(x, other.x); return *this; } ModInt operator *(const ModInt& other) const { return ModInt(__mul(x, other.x)); } ModInt& operator *=(const ModInt& other) { x = __mul(x, other.x); return *this; } ModInt operator /(const ModInt& other) const { return ModInt(__div(x, other.x)); } ModInt& operator /=(const ModInt& other) { x = __div(x, other.x); return *this; } ModInt pow(const ModInt& other) const { return ModInt(pow(x, other.x)); } ModInt operator +() const { return ModInt<Mod>(x); } ModInt operator -() const { return ModInt<Mod>(0) - *this; } bool operator ==(const ModInt& other) const { return x == other.x; } bool operator !=(const ModInt& other) const { return x != other.x; } friend istream& operator >>(istream& in, ModInt<Mod>& val) { in >> val.x; return in; } friend ostream& operator <<(ostream& out, const ModInt<Mod>& val) { out << val.x; return out; } }; template <int Mod> class DSU { private: struct Group { ModInt<Mod> ans, rectbottom; ModInt<Mod> dx; int lasth; Group() :ans(0), rectbottom(0), dx(0), lasth(0) {} }; int n; vector<int> p, d; vector<Group> info; int get_par(int v) { if (v == p[v]) { return v; } return p[v] = get_par(p[v]); } public: DSU(int n_):n(n_) { p.resize(n); iota(p.begin(), p.end(), 0); d.resize(n); info.resize(n); } void setInfo(int i, ll w, int h) { info[i].dx = ModInt<Mod>(w); info[i].lasth = h; } void updateInfo(int i, int h) { i = get_par(i); ModInt<Mod> dh(info[i].lasth - h); info[i].ans += info[i].rectbottom * dh + info[i].dx * (info[i].dx + 1) * dh * (dh + 1) / ModInt<Mod>(4); info[i].rectbottom += info[i].dx * (info[i].dx + 1) * dh / ModInt<Mod>(2); info[i].lasth = h; } void unite(int i, int j) { i = get_par(i); j = get_par(j); if (i != j) { if (d[i] > d[j]) { swap(i, j); } p[i] = j; if (d[i] == d[j]) { d[j]++; } info[j].ans += info[i].ans; info[j].rectbottom += info[i].rectbottom; info[j].dx += info[i].dx; } } ModInt<Mod> get_answer(int i) { return info[get_par(i)].ans; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(0); const int Mod = 1e9 + 7; int n; cin >> n; vector<int> h(n), w(n); for (int i = 0; i < n; ++i) { cin >> h[i]; } for (int i = 0; i < n; ++i) { cin >> w[i]; } vector<pair<int, int>> ev(n); for (int i = 0; i < n; ++i) { ev[i] = { h[i], i }; } sort(ev.begin(), ev.end(), [&](const pair<int, int>& a, const pair<int, int>& b) -> bool { return a.first > b.first; }); vector<bool> active(n); DSU<Mod> d(n); for (auto& e : ev) { int ind = e.second; active[ind] = true; d.setInfo(ind, w[ind], h[ind]); if (ind > 0 && active[ind - 1]) { d.updateInfo(ind - 1, h[ind]); d.unite(ind, ind - 1); } if (ind < n - 1 && active[ind + 1]) { d.updateInfo(ind + 1, h[ind]); d.unite(ind, ind + 1); } } d.updateInfo(0, 0); cout << d.get_answer(0) << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...