Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- _ __ U _____ u _ __
- |"|/ / \| ___"|/ |"|/ /
- | ' / | _|" | ' /
- U/| . \\u | |___ U/| . \\u
- |_|\_\ |_____| |_|\_\
- ,-,>> \\,-.<< >>,-,>> \\,-.
- \.) (_/(__) (__)\.) (_/
- */
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- typedef long double ld;
- typedef unsigned long long ull;
- typedef vector<int> vi;
- typedef pair<int, int> pii;
- typedef pair<long long, long long> pll;
- #define zhfs main
- #define mp(a, b) make_pair(a, b)
- #define fi first
- #define se second
- #define re return
- #define forn(i, n) for (int i = 1; i <= n; i++)
- struct segmentTree
- {
- vector<ull> t, m;
- segmentTree(int n)
- {
- t.resize(4 * n + 7);
- m.resize(4 * n + 7, (ull)-1);
- }
- void push(int v)
- {
- if (m[v] == (ull)-1) re;
- m[v + v] = m[v];
- m[v + v + 1] = m[v];
- m[v] = (ull)-1;
- }
- ull getv(int v, int tl, int tr)
- {
- if (m[v] == (ull)-1) re t[v];
- re m[v] * (tr - tl + 1);
- }
- void draw(int v, int tl, int tr, int l, int r, int x)
- {
- if (r < tl || l > tr) re;
- if (tl >= l && tr <= r)
- {
- m[v] = x;
- re;
- }
- push(v);
- int tm = (tl + tr) >> 1;
- draw(v + v, tl, tm, l, r, x);
- draw(v + v + 1, tm + 1, tr, l, r, x);
- t[v] = getv(v + v, tl, tm) + getv(v + v + 1, tm + 1, tr);
- }
- ull getSum(int v, int tl, int tr, int l, int r)
- {
- if (r < tl || l > tr) re 0ULL;
- if (tl >= l && tr <= r) re getv(v, tl, tr);
- push(v);
- int tm = (tl + tr) >> 1;
- ll res = getSum(v + v, tl, tm, l, r) + getSum(v + v + 1, tm + 1, tr, l, r);
- t[v] = getv(v + v, tl, tm) + getv(v + v + 1, tm + 1, tr);
- re res;
- }
- };
- const int MAXN = 200 * 1000 + 7;
- ull a[MAXN];
- void printTree(segmentTree &st, int n)
- {
- for (int i = 1; i <= n; i++)
- {
- printf("%llu ", st.getSum(1, 1, n, i, i));
- }
- printf("\n");
- }
- int zhfs()
- {
- #ifdef LOCAL
- freopen("input.txt", "r", stdin);
- #endif
- int n;
- scanf("%d", &n);
- for (int i = 1; i <= n; i++)
- {
- scanf("%llu", &a[i]);
- }
- vector<pair<int, ull> > minStack, maxStack;
- minStack.push_back(make_pair(0, 0));
- maxStack.push_back(make_pair(0, MAXN));
- segmentTree minTree(n + 1), maxTree(n + 1);
- ull sumMin = 0, sumMax = 0, sumMul = 0, res = 0;
- for (int i = 1; i <= n; i++)
- {
- while (minStack.back().second > a[i])
- {
- int sz = (int)minStack.size();
- int l = minStack[sz - 2].first + 1, r = minStack[sz - 1].first;
- sumMin -= minStack[sz - 1].se * minStack[sz - 1].se * (r - l + 1);
- sumMul += 2ULL * maxTree.getSum(1, 1, n, l, r) * minStack[sz - 1].se;
- minTree.draw(1, 1, n, l, r, 0);
- minStack.pop_back();
- }
- while (maxStack.back().second < a[i])
- {
- int sz = (int)maxStack.size();
- int l = maxStack[sz - 2].first + 1, r = maxStack[sz - 1].first;
- sumMax -= maxStack[sz - 1].se * maxStack[sz - 1].se * (r - l + 1);
- sumMul += 2ULL * minTree.getSum(1, 1, n, l, r) * maxStack[sz - 1].se;
- maxTree.draw(1, 1, n, l, r, 0);
- maxStack.pop_back();
- }
- // printf("AFTER POP:\n");
- // printf("MINTREE: ");
- // printTree(minTree, n);
- // printf("MAXTREE: ");
- // printTree(maxTree, n);
- // printf("sumMin = %lld, sumMax = %lld, sumMul = %lld\n", (ll)sumMin, (ll)sumMax, (ll)sumMul);
- sumMin += a[i] * a[i] * (i - minStack.back().fi);
- sumMax += a[i] * a[i] * (i - maxStack.back().fi);
- sumMul -= 2ULL * a[i] * maxTree.getSum(1, 1, n, minStack.back().fi + 1, i);
- minTree.draw(1, 1, n, minStack.back().fi + 1, i, a[i]);
- sumMul -= 2ULL * a[i] * minTree.getSum(1, 1, n, maxStack.back().fi + 1, i);
- maxTree.draw(1, 1, n, maxStack.back().fi + 1, i, a[i]);
- res += sumMin;
- res += sumMax;
- res += sumMul;
- minStack.push_back(make_pair(i, a[i]));
- maxStack.push_back(make_pair(i, a[i]));
- // printf("AFTER PUSH:\n");
- // printf("MINTREE: ");
- // printTree(minTree, n);
- // printf("MAXTREE: ");
- // printTree(maxTree, n);
- // printf("sumMin = %lld, sumMax = %lld, sumMul = %lld\n", (ll)sumMin, (ll)sumMax, (ll)sumMul);
- }
- printf("%llu\n", res);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement