QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#94538 | #2070. Heavy Stones | hos_lyric | TL | 313ms | 71872kb | C++14 | 8.5kb | 2023-04-06 16:25:13 | 2023-04-06 16:25:15 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
// T: monoid representing information of an interval.
// T() should return the identity.
// T(S s) should represent a single element of the array.
// T::pull(const T &l, const T &r) should pull two intervals.
template <class T> struct SegmentTreePoint {
int logN, n;
vector<T> ts;
SegmentTreePoint() {}
explicit SegmentTreePoint(int n_) {
for (logN = 0, n = 1; n < n_; ++logN, n <<= 1) {}
ts.resize(n << 1);
}
template <class S> explicit SegmentTreePoint(const vector<S> &ss) {
const int n_ = ss.size();
for (logN = 0, n = 1; n < n_; ++logN, n <<= 1) {}
ts.resize(n << 1);
for (int i = 0; i < n_; ++i) at(i) = T(ss[i]);
build();
}
T &at(int i) {
return ts[n + i];
}
void build() {
for (int u = n; --u; ) pull(u);
}
inline void pull(int u) {
ts[u].pull(ts[u << 1], ts[u << 1 | 1]);
}
// Changes the value of point a to s.
template <class S> void change(int a, const S &s) {
assert(0 <= a); assert(a < n);
ts[a += n] = T(s);
for (; a >>= 1; ) pull(a);
}
// Applies T::f(args...) to point a.
template <class F, class... Args>
void ch(int a, F f, Args &&... args) {
assert(0 <= a); assert(a < n);
(ts[a += n].*f)(args...);
for (; a >>= 1; ) pull(a);
}
// Calculates the product for [a, b).
T get(int a, int b) {
assert(0 <= a); assert(a <= b); assert(b <= n);
if (a == b) return T();
a += n; b += n;
T prodL, prodR, t;
for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
if (aa & 1) { t.pull(prodL, ts[aa++]); prodL = t; }
if (bb & 1) { t.pull(ts[--bb], prodR); prodR = t; }
}
t.pull(prodL, prodR);
return t;
}
// Calculates T::f(args...) of a monoid type for [a, b).
// op(-, -) should calculate the product.
// e() should return the identity.
template <class Op, class E, class F, class... Args>
#if __cplusplus >= 201402L
auto
#else
decltype((std::declval<T>().*F())())
#endif
get(int a, int b, Op op, E e, F f, Args &&... args) {
assert(0 <= a); assert(a <= b); assert(b <= n);
if (a == b) return e();
a += n; b += n;
auto prodL = e(), prodR = e();
for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
if (aa & 1) prodL = op(prodL, (ts[aa++].*f)(args...));
if (bb & 1) prodR = op((ts[--bb].*f)(args...), prodR);
}
return op(prodL, prodR);
}
// Find min b s.t. T::f(args...) returns true,
// when called for the partition of [a, b) from left to right.
// Returns n + 1 if there is no such b.
template <class F, class... Args>
int findRight(int a, F f, Args &&... args) {
assert(0 <= a); assert(a <= n);
if ((T().*f)(args...)) return a;
if (a == n) return n + 1;
a += n;
for (; ; a >>= 1) if (a & 1) {
if ((ts[a].*f)(args...)) {
for (; a < n; ) {
if (!(ts[a <<= 1].*f)(args...)) ++a;
}
return a - n + 1;
}
++a;
if (!(a & (a - 1))) return n + 1;
}
}
// Find max a s.t. T::f(args...) returns true,
// when called for the partition of [a, b) from right to left.
// Returns -1 if there is no such a.
template <class F, class... Args>
int findLeft(int b, F f, Args &&... args) {
assert(0 <= b); assert(b <= n);
if ((T().*f)(args...)) return b;
if (b == 0) return -1;
b += n;
for (; ; b >>= 1) if ((b & 1) || b == 2) {
if ((ts[b - 1].*f)(args...)) {
for (; b <= n; ) {
if (!(ts[(b <<= 1) - 1].*f)(args...)) --b;
}
return b - n - 1;
}
--b;
if (!(b & (b - 1))) return -1;
}
}
};
////////////////////////////////////////////////////////////////////////////////
// ((nu, de), (cost, id))
using Slope = pair<pair<Int, Int>, pair<Int, int>>;
// weight: ..., 2, 1
struct Node {
Int sz, sum0, sum1;
Node() : sz(0), sum0(0), sum1(0) {}
Node(const Slope &f) : sz(f.first.second), sum0(f.first.first), sum1(f.second.first) {}
void pull(const Node &l, const Node &r) {
sz = l.sz + r.sz;
sum0 = l.sum0 + r.sum0;
sum1 = l.sum1 + l.sum0 * r.sz + r.sum1;
}
};
int N;
vector<Int> A;
int main() {
for (; ~scanf("%d", &N); ) {
A.resize(N);
for (int i = 0; i < N; ++i) {
scanf("%lld", &A[i]);
}
vector<Slope> fs;
// i-1 -> i
vector<vector<int>> addss(N + 1), remss(N + 1);
// to the left
{
int len = 0;
vector<Slope> stack(N);
for (int i = 0; i < N; ++i) {
Int p = A[i];
Int q = 1;
for (; len >= 1; ) {
const Int pp = stack[len - 1].first.first;
const Int qq = stack[len - 1].first.second;
if (p * qq >= pp * q) {
remss[i + 1].push_back(stack[len - 1].second.second);
p += pp;
q += qq;
--len;
} else {
break;
}
}
Int cost = 0, now = 0;
for (int di = 0; di < q; ++di) {
cost += now += A[i - di];
}
const int id = fs.size();
fs.emplace_back(make_pair(p, q), make_pair(cost, id));
addss[i + 1].push_back(id);
stack[len++] = fs.back();
}
}
// to the right
{
int len = 0;
vector<Slope> stack(N);
for (int i = N; --i > 0; ) {
Int p = A[i];
Int q = 1;
for (; len >= 1; ) {
const Int pp = stack[len - 1].first.first;
const Int qq = stack[len - 1].first.second;
if (p * qq >= pp * q) {
addss[i].push_back(stack[len - 1].second.second);
p += pp;
q += qq;
--len;
} else {
break;
}
}
Int cost = 0, now = 0;
for (int di = 0; di < q; ++di) {
cost += now += A[i + di];
}
const int id = fs.size();
fs.emplace_back(make_pair(p, q), make_pair(cost, id));
remss[i].push_back(id);
stack[len++] = fs.back();
}
for (; len >= 1; ) {
addss[0].push_back(stack[--len].second.second);
}
}
sort(fs.begin(), fs.end(), [&](const Slope &f0, const Slope &f1) -> bool {
const Int p0 = f0.first.first;
const Int q0 = f0.first.second;
const Int p1 = f1.first.first;
const Int q1 = f1.first.second;
return (p0 * q1 < p1 * q0);
});
const int fsLen = fs.size();
// cerr<<"fs = "<<fs<<endl;
// cerr<<"addss = "<<addss<<endl;
// cerr<<"remss = "<<remss<<endl;
vector<int> poss(fsLen);
for (int k = 0; k < fsLen; ++k) {
poss[fs[k].second.second] = k;
}
vector<Int> ans(N);
SegmentTreePoint<Node> seg(fsLen);
for (int i = 0; i < N; ++i) {
for (const int j : addss[i]) {
const int k = poss[j];
// cerr<<"add "<<fs[k]<<endl;
seg.change(k, fs[k]);
}
for (const int j : remss[i]) {
const int k = poss[j];
// cerr<<"rem "<<fs[k]<<endl;
seg.change(k, Node());
}
// cerr<<" sz = "<<seg.ts[1].sz<<", sum0 = "<<seg.ts[1].sum0<<", sum1 = "<<seg.ts[1].sum1<<endl;
ans[i] = seg.ts[1].sum1;
ans[i] += (N - 1) * A[i];
}
for (int i = 0; i < N; ++i) {
if (i) printf(" ");
printf("%lld", ans[i]);
}
puts("");
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 3720kb
input:
5 2 1 3 5 4
output:
35 35 36 43 49
result:
ok single line: '35 35 36 43 49'
Test #2:
score: 0
Accepted
time: 2ms
memory: 3572kb
input:
10 18 37 81 6 58 99 87 34 75 9
output:
2637 2637 2657 2657 2695 2949 2995 2905 2880 2880
result:
ok single line: '2637 2637 2657 2657 2695 2949 2995 2905 2880 2880'
Test #3:
score: 0
Accepted
time: 297ms
memory: 70648kb
input:
200000 479735 430060 863649 878892 889364 241972 927862 32858 714406 674598 88114 438434 167733 457299 951288 510096 635193 504974 649221 617914 223711 812277 364169 746142 836563 825312 994240 198961 567906 905208 509572 744710 891294 928176 833980 985385 858440 50835 86130 324862 796245 935992 383...
output:
9992833979971052 9992833979971052 9992833980354966 9992779245594768 9992703452732543 9992625566170070 9992625565960956 9992591568400874 9992591568400874 9992591568189384 9992591567396390 9992591567396390 9992591567476009 9992591567864059 9992591571455644 9992591572452874 9992591574009688 99925915745...
result:
ok single line: '9992833979971052 9992833979971...4203005830427 10004203006781811'
Test #4:
score: 0
Accepted
time: 313ms
memory: 71872kb
input:
200000 754184 13065 865956 768626 744822 919059 583237 600724 524170 165425 246285 226816 966566 610515 550388 715978 549675 83917 323652 423422 266395 285394 470160 472551 743112 879255 493014 992502 158286 301973 857254 395231 282559 806597 243952 205846 976027 598783 69632 165916 622634 620757 34...
output:
10014997841701475 10014947015238274 10014947015238274 10014947015993835 10014917512559448 10014868558588544 10014784759644306 10014768120716895 10014747984710856 10014743158715252 10014743158715252 10014743158776643 10014743160298065 10014743161445632 10014743159820460 10014743158450587 100147431338...
result:
ok single line: '10014997841701475 100149470152...87021303093862 9987021303093862'
Test #5:
score: 0
Accepted
time: 292ms
memory: 71264kb
input:
200000 783905 465734 702646 342070 382378 612468 565748 741917 648664 523500 182013 89445 129572 26912 175340 537820 717500 718402 563606 124584 111640 830294 957543 449869 563613 901195 496363 918492 226878 429682 770972 654243 222706 539682 471463 654386 31958 381760 352938 783523 851106 354268 75...
output:
9985525267421517 9985468293020605 9985468291830972 9985434229308153 9985434229308153 9985434229224741 9985434226842360 9985434224335794 9985404337013738 9985374417560553 9985369520866620 9985369520652405 9985369520589872 9985369520589872 9985369520721535 9985369522444873 9985369525429091 99853695285...
result:
ok single line: '9985525267421517 9985468293020...75790145914810 9975830720773589'
Test #6:
score: 0
Accepted
time: 273ms
memory: 71404kb
input:
200000 853686 20716 174697 869738 857025 507882 375300 849975 893238 468077 184722 535631 383301 657603 49942 235054 316530 521594 464021 979922 188332 335907 114903 261684 434608 966750 619976 793830 275183 498775 690216 769588 589049 958997 995520 845297 350658 198715 707600 18882 203867 132974 16...
output:
10007482900924066 10007412205735064 10007412205735064 10007412206584086 10007412208102723 10007412205041250 10007412203774418 10007412203774418 10007381409966150 10007302822767145 10007302821693099 10007302821693099 10007302821528524 10007302820980147 10007302819330353 10007302819330353 100073028195...
result:
ok single line: '10007482900924066 100074122057...0782048899392 10000853953946590'
Test #7:
score: 0
Accepted
time: 296ms
memory: 71612kb
input:
200000 282721 513944 210659 728001 402993 628298 260323 376301 404417 439890 298253 575700 991264 735782 387209 874869 995018 778731 247456 286146 598879 216939 91609 177310 82415 36330 265803 953105 564707 201163 357501 390048 142474 266916 46616 539260 570794 792662 270237 67158 511870 166602 9035...
output:
10008509175990736 10008509175918674 10008509175918674 10008509176578011 10008509171139661 10008509170903880 10008509157826476 10008509157826476 10008509157970570 10008509158067444 10008509158067444 10008509158889313 10008509162066449 10008509131249736 10008509108213966 10008509107556161 100084882028...
result:
ok single line: '10008509175990736 100085091759...6908130262195 10006908130262195'
Test #8:
score: -100
Time Limit Exceeded
input:
200000 22 25 28 34 59 61 68 80 108 116 119 121 121 123 131 131 141 143 152 166 167 174 184 215 228 231 264 279 307 309 313 314 327 339 341 362 381 399 414 421 430 449 477 486 490 500 502 508 529 529 562 566 569 571 585 597 641 650 658 675 680 684 698 721 723 724 731 732 737 755 784 785 810 813 817 8...