This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
#include <iostream>
/**
* Compute the greatest common divisor d of a and b together
* with the x and y such that ax + by = d using the extended Euclidean algorithm
*
* @param integers a, b whose gcd will be computed, references x, y where values will be stored
* @returns greatest common divisor of a and b
*/
template<typename T1, typename T2>
T1 extgcd(const T1& a, const T1& b, T2 &x, T2 &y) {
x = 1; y = 0;
T1 a1(a), b1(b);
T2 x1 = 0, y1 = 1;
while (b1 != 0) {
T1 q = a1 / b1;
tie(x, x1) = make_pair(x1, x - q * x1);
tie(y, y1) = make_pair(y1, y - q * y1);
tie(a1, b1) = make_pair(b1, a1 - q * b1);
}
return a1;
}
/**
* Modular integer implementation
* NOT completely tested!
*/
template<const int MOD>
class modint {
private: int x;
public:
modint() : x(0) {}
template<typename T>
void set(const T _x, bool raw = false) {
if (raw) x = _x;
else {
x = _x % MOD;
if (x < 0) x += MOD;
}
}
template<typename T>
modint(const T &_x, bool raw = false) {
set(_x, raw);
}
template<typename T>
modint<MOD> &operator=(const T &_x) {
set(_x);
return *this;
}
modint<MOD> &operator+=(const modint<MOD> &rhs) {
x += rhs.x;
if (x >= MOD) x -= MOD;
return *this;
}
friend modint<MOD> operator+(modint<MOD> lhs, const modint<MOD> &rhs) {
lhs += rhs;
return lhs;
}
modint<MOD> &operator-=(const modint<MOD> &rhs) {
x -= rhs.x;
if (x < 0) x += MOD;
return *this;
}
friend modint<MOD> operator-(modint<MOD> lhs, const modint<MOD> &rhs) {
lhs -= rhs;
return lhs;
}
modint<MOD> &operator*=(const modint<MOD> &rhs) {
x = (unsigned long long) x * rhs.x % MOD;
return *this;
}
friend modint<MOD> operator*(modint<MOD> lhs, const modint<MOD> &rhs) {
lhs *= rhs;
return lhs;
}
modint<MOD> inv() const {
modint x1, y1;
extgcd(x, MOD, x1, y1);
return move(x1);
}
modint<MOD> &operator/=(const modint<MOD> &rhs) {
operator*=(rhs.inv());
return *this;
}
friend modint<MOD> operator/(modint<MOD> lhs, const modint<MOD> &rhs) {
lhs /= rhs;
return lhs;
}
modint<MOD> &operator++() {
operator+=(1);
return *this;
}
modint<MOD> operator++(int) {
modint<MOD> old = *this;
operator++();
return old;
}
modint<MOD> &operator--() {
operator-=(1);
return *this;
}
modint<MOD> operator--(int) {
modint<MOD> old = *this;
operator--();
return old;
}
template<typename T>
operator T() const {
return x;
}
int val() const {
return x;
}
};
template<const int MOD, typename T>
modint<MOD> pow(modint<MOD> a, T b) {
modint<MOD> ans(1, true);
while (b != 0) {
if (b & 1) ans *= a;
a *= a;
b >>= 1;
}
return ans;
}
template<const int MOD>
std::istream &operator>>(std::istream &is, modint<MOD> &x) {
unsigned int _x;
is >> _x;
x.set(_x, true);
return is;
}
template<const int MOD>
std::ostream &operator<<(std::ostream &os, const modint<MOD> &x) {
os << x.val();
return os;
}
using mint1000000007 = modint<1000000007>;
using mint998244353 = modint<998244353>;
using mint = mint1000000007;
mint f(mint h, mint w) {
return h * (h + 1) * w * (w + 1) / 4;
}
class dsu {
private:
vector<int> p, rank;
vector<mint> sz;
public:
dsu(int n, const vector<mint> &_sz) : sz(_sz) {
p.assign(n, -1);
rank.assign(n, 0);
}
int root(int x) {
if (p[x] == -1) {
return x;
}
return (p[x] = root(p[x]));
}
bool same_set(int x, int y) {
return (root(x) == root(y));
}
void connect(int x, int y) {
x = root(x); y = root(y);
if (x != y) {
if (rank[x] > rank[y]) {
p[y] = x;
sz[x] += sz[y];
} else {
p[x] = y;
sz[y] += sz[x];
if (rank[x] == rank[y]) {
rank[y]++;
}
}
}
}
mint st_sz(int x) {
return sz[root(x)];
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
vector<mint> h(n), w(n);
map<int, vector<mint>, greater<int> > mp;
for (int i = 0; i < n; i++) {
cin >> h[i];
mp[h[i]].push_back(i);
}
for (int i = 0; i < n; i++) {
cin >> w[i];
}
dsu g(n, w);
vector<bool> b(n, false);
mint ans = 0;
for (auto& p : mp) {
for (auto& x : p.second) {
b[x] = true;
if (x.val() > 0 && b[x - 1] && !g.same_set(x, x - 1)) {
ans -= f(p.first, g.st_sz(x - 1));
g.connect(x, x - 1);
}
if (x.val() < n - 1 && b[x + 1] && !g.same_set(x, x + 1)) {
ans -= f(p.first, g.st_sz(x + 1));
g.connect(x, x + 1);
}
ans += f(p.first, g.st_sz(x));
}
}
cout << ans << '\n';
return 0;
}
Compilation message (stderr)
fancyfence.cpp: In instantiation of 'modint<MOD> modint<MOD>::inv() const [with int MOD = 1000000007]':
fancyfence.cpp:97:24: required from 'modint<MOD>& modint<MOD>::operator/=(const modint<MOD>&) [with int MOD = 1000000007]'
fancyfence.cpp:102:13: required from 'modint<1000000007> operator/(modint<1000000007>, const modint<1000000007>&)'
fancyfence.cpp:169:40: required from here
fancyfence.cpp:93:23: warning: moving a local object in a return statement prevents copy elision [-Wpessimizing-move]
93 | return move(x1);
| ^
fancyfence.cpp:93:23: note: remove 'std::move' call
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |