Submission #1168943

#TimeUsernameProblemLanguageResultExecution timeMemory
1168943VahanAbrahamFlooding Wall (BOI24_wall)C++20
70 / 100
5095 ms139952 KiB
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <algorithm> #include <cstring> #include <cstdio> #include <sstream> #include <map> #include <stack> #include <set> #include <queue> #include <deque> #include <unordered_set> #include <unordered_map> #include <math.h> #include <cmath> #include <vector> #include <iomanip> #include <random> #include <chrono> #include <bitset> using namespace std; #define ll long long #define fr first #define sc second #define pb push_back #define US freopen(".in", "r", stdin); freopen(".out", "w", stdout); ll gcd(ll a, ll b) { if (a == 0 || b == 0) { return max(a, b); } if (a <= b) { return gcd(a, b % a); } else { return gcd(a % b, b); } } ll lcm(ll a, ll b) { return (a / gcd(a, b)) * b; } const int N = 1000005; const ll oo = 1000000000000000000, MOD = 1000000007; int a[4][N], index_1[4][N], n, qan[N], sztr; ll num_in_index[N], pw[N], pat[N]; struct NODE { int size; ll v, sm; }; NODE t[3][4 * N]; void push(int ty, int x) { if (t[ty][x].v == 1 || t[ty][x].size == 1) { return; } ll val = t[ty][x].v; t[ty][2 * x].sm = t[ty][2 * x].sm * val % MOD; t[ty][2 * x + 1].sm = t[ty][2 * x + 1].sm * val % MOD; t[ty][2 * x].v = t[ty][2 * x].v * val % MOD; t[ty][2 * x + 1].v = t[ty][2 * x + 1].v * val % MOD; t[ty][x].v = 1; } void build(int ty, int lx, int rx, int x) { t[ty][x].v = 1; t[ty][x].sm = 0; if (lx == rx) { t[ty][x].size = 1; return; } int m = (lx + rx) / 2; build(ty, lx, m, 2 * x); build(ty, m + 1, rx, 2 * x + 1); t[ty][x].size = t[ty][2 * x].size + t[ty][2 * x + 1].size; } void seet(int id, ll val, int lx, int rx, int x) { push(1, x); push(2, x); if (lx == rx) { t[2][x].sm += (num_in_index[lx] * val % MOD); if (t[2][x].sm >= MOD) { t[2][x].sm -= MOD; } t[1][x].sm = (t[1][x].sm + val); if (t[1][x].sm >= MOD) { t[1][x].sm -= MOD; } return; } int m = (lx + rx) / 2; if (id <= m) { seet(id, val, lx, m, 2 * x); } else { seet(id, val, m + 1, rx, 2 * x + 1); } t[1][x].sm = (t[1][2 * x].sm + t[1][2 * x + 1].sm); if (t[1][x].sm >= MOD) { t[1][x].sm -= MOD; } t[2][x].sm = (t[2][2 * x].sm + t[2][2 * x + 1].sm); if (t[2][x].sm >= MOD) { t[2][x].sm -= MOD; } } void ubd(int l, int r, int val, int lx, int rx, int x) { push(1, x); push(2, x); if (lx > r || rx < l) { return; } if (l <= lx && rx <= r) { t[1][x].sm = t[1][x].sm * (ll)val % MOD; t[1][x].v = t[1][x].v * (ll)val % MOD; t[2][x].sm = t[2][x].sm * (ll)val % MOD; t[2][x].v = t[2][x].v * (ll)val % MOD; return; } int m = (lx + rx) / 2; ubd(l, r, val, lx, m, 2 * x); ubd(l, r, val, m + 1, rx, 2 * x + 1); t[1][x].sm = (t[1][2 * x].sm + t[1][2 * x + 1].sm); if (t[1][x].sm >= MOD) { t[1][x].sm -= MOD; } t[2][x].sm = (t[2][2 * x].sm + t[2][2 * x + 1].sm); if (t[2][x].sm >= MOD) { t[2][x].sm -= MOD; } } int sum(int ty, int l, int r, int lx, int rx, int x) { push(ty, x); if (lx > r || rx < l) { return 0; } if (l <= lx && rx <= r) { return t[ty][x].sm; } int m = (lx + rx) / 2; int smans = (sum(ty, l, r, lx, m, 2 * x) + sum(ty, l, r, m + 1, rx, 2 * x + 1)); if (smans >= MOD) { smans -= MOD; } return smans; } void solv(int vorna) { build(1, 1, sztr, 1); build(2, 1, sztr, 1); for (int i = 1; i <= n; ++i) { int ind2 = i; if (vorna == 2) { ind2 = n - i + 1; } int sm2 = sum(1, 1, index_1[2][ind2], 1, sztr, 1); int sm1 = sum(1, 1, index_1[1][ind2], 1, sztr, 1); ubd(1, index_1[2][ind2] - 1, 0, 1, sztr, 1); ubd(index_1[1][ind2] + 1, sztr, 2, 1, sztr, 1); if (i != 1) { seet(index_1[2][ind2], sm2, 1, sztr, 1); seet(index_1[1][ind2], sm1, 1, sztr, 1); } else { seet(index_1[2][ind2], 1, 1, sztr, 1); seet(index_1[1][ind2], 1, 1, sztr, 1); } pat[i] += sum(2, 1, sztr, 1, sztr, 1) * pw[n - i] % MOD; pat[i] %= MOD; } } void solve() { cin >> n; pw[0] = 1; for (int i = 1; i <= n; ++i) { pw[i] = pw[i - 1] * 2LL % MOD; } for (int i = 1; i <= n; ++i) { cin >> a[1][i]; } for (int i = 1; i <= n; ++i) { cin >> a[2][i]; if (a[1][i] < a[2][i]) { swap(a[1][i], a[2][i]); } } vector <pair<int, pair<int, int>>> vec; for (int i = 1; i <= n; ++i) { vec.pb({ a[1][i],{i,1} }); vec.pb({ a[2][i],{i,2} }); } vector<int> index_in_real(vec.size() + 5); sort(vec.begin(), vec.end()); for (int i = 0; i < vec.size(); ++i) { num_in_index[i + 1] = vec[i].fr; index_in_real[i] = vec[i].sc.fr; index_1[vec[i].sc.sc][vec[i].sc.fr] = i + 1; } sztr = vec.size(); solv(1); for (int i = 1; i <= n / 2; ++i) { swap(a[1][i], a[1][n - i + 1]); swap(a[2][i], a[2][n - i + 1]); } solv(2); int canstartsmx = 0; for (int i = vec.size() - 1; i >= 0; --i) { int id_real = index_in_real[i]; qan[id_real]++; if (qan[id_real] == 2) { canstartsmx = i; break; } } for (int i = vec.size() - 1; i >= 0; --i) { int id_real = index_in_real[i]; qan[id_real] = 0; } ll ans2 = 0, cnt = 0, ans1 = 0; for (int i = 0; i < vec.size(); ++i) { if (canstartsmx <= i) { ans2 += (ll)n * pw[cnt] % MOD * vec[i].fr % MOD; if (ans2 >= MOD) { ans2 -= MOD; } } int id_real = index_in_real[i]; qan[id_real]++; if (qan[id_real] == 2) { ++cnt; } } for (int i = 1; i <= n; ++i) { ans1 += pat[i]; if (ans1 >= MOD) { ans1 -= MOD; } } ll ans3 = 0; for (int i = 1; i <= n; ++i) { for (int k = 1; k <= 2; ++k) { ans3 += (ll)a[k][i] * pw[n - 1] % MOD; if (ans3 >= MOD) { ans3 -= MOD; } } } cout << (ans1 - ans2 + MOD - ans3 + MOD) % MOD << endl; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); //US int tt = 1; //cin >> tt; while (tt--) { solve(); } }
#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...