Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifdef DEBUG
- #define _GLIBCXX_DEBUG
- #endif
- #include <bits/stdc++.h>
- using namespace std;
- typedef long double ld;
- #ifdef DEBUG
- #define eprintf(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
- #else
- #define eprintf(...) ;
- #endif
- #define sz(x) ((int) (x).size())
- #define TASK "text"
- const int inf = (int) 1.01e9;
- const long long infll = (long long) 1.01e18;
- const ld eps = 1e-9;
- const ld pi = acos((ld) -1);
- #ifdef DEBUG
- mt19937 mrand(300);
- #else
- mt19937 mrand(chrono::steady_clock::now().time_since_epoch().count());
- #endif
- int rnd(int x) {
- return mrand() % x;
- }
- void precalc() {
- }
- struct point {
- long long x, y;
- point(): x(0), y(0) {}
- point(long long xx, long long yy): x(xx), y(yy) {}
- point operator + (const point &p) const {
- return point(x + p.x, y + p.y);
- }
- point operator - (const point &p) const {
- return point(x - p.x, y - p.y);
- }
- long long operator ^ (const point &p) const {
- return x * p.y - y * p.x;
- }
- };
- bool operator < (const point &a, const point &b) {
- return (a ^ b) > 0;
- }
- bool operator > (const point &a, const point &b) {
- return (a ^ b) < 0;
- }
- const int maxn = (int) 2e5 + 5;
- int n;
- int a[maxn];
- bool read() {
- if (scanf("%d", &n) < 1) {
- return false;
- }
- for (int i = 0; i < n; i++) {
- scanf("%d", &a[i]);
- }
- return true;
- }
- long long ans[maxn];
- vector<point> ch[2];
- vector<point> s[2];
- vector<point> dels[maxn];
- long long res;
- void del(int t) {
- assert(!ch[t].empty());
- point p = ch[t].back();
- ch[t].pop_back();
- s[t].pop_back();
- int pos;
- if (!t) {
- pos = lower_bound(ch[!t].begin(), ch[!t].end(), p, greater<point>()) - ch[!t].begin();
- } else {
- pos = upper_bound(ch[!t].begin(), ch[!t].end(), p, greater<point>()) - ch[!t].begin();
- }
- res -= s[!t][pos].x * p.y;
- res -= (s[!t].back().y - s[!t][pos].y) * p.x;
- }
- void add(int t, const point &p) {
- ch[t].push_back(p);
- point curs = s[t].back() + p;
- s[t].push_back(curs);
- int pos;
- if (!t) {
- pos = lower_bound(ch[!t].begin(), ch[!t].end(), p, greater<point>()) - ch[!t].begin();
- } else {
- pos = upper_bound(ch[!t].begin(), ch[!t].end(), p, greater<point>()) - ch[!t].begin();
- }
- res += s[!t][pos].x * p.y;
- res += (s[!t].back().y - s[!t][pos].y) * p.x;
- }
- long long s0[maxn], s1[maxn];
- void solve() {
- ch[0] = {};
- s[0] = {point()};
- for (int i = 0; i < n; i++) {
- point cur = point(1, a[i]);
- dels[i].clear();
- while (!ch[0].empty() && !(cur < ch[0].back())) {
- dels[i].push_back(ch[0].back());
- cur = cur + ch[0].back();
- ch[0].pop_back();
- s[0].pop_back();
- }
- ch[0].push_back(cur);
- point curs = s[0].back() + cur;
- s[0].push_back(curs);
- }
- ch[1] = {};
- s[1] = {point()};
- res = 0;
- for (int i = n - 1; i >= 0; i--) {
- del(0);
- while (!dels[i].empty()) {
- point cur = dels[i].back();
- dels[i].pop_back();
- add(0, cur);
- }
- ans[i] = res;
- point cur = point(1, a[i]);
- while (!ch[1].empty() && !(cur < ch[1].back())) {
- cur = cur + ch[1].back();
- del(1);
- }
- add(1, cur);
- }
- s0[0] = 0;
- s1[0] = 0;
- for (int i = 0; i < n; i++) {
- s0[i + 1] = s0[i] + a[i];
- s1[i + 1] = s1[i] + (long long) a[i] * i;
- }
- for (int i = 0; i < n; i++) {
- ans[i] += n * (s0[n] - s0[i + 1]);
- ans[i] -= s1[n] - s1[i + 1];
- ans[i] += s0[i];
- ans[i] += s1[i];
- ans[i] += (long long) a[i] * (n - 1);
- }
- for (int i = 0; i < n; i++) {
- printf("%lld ", ans[i]);
- }
- printf("\n");
- }
- int main() {
- precalc();
- #ifdef DEBUG
- assert(freopen(TASK ".in", "r", stdin));
- assert(freopen(TASK ".out", "w", stdout));
- #endif
- while (read()) {
- solve();
- #ifdef DEBUG
- eprintf("Time %.2f\n", (double) clock() / CLOCKS_PER_SEC);
- #endif
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment