QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#353767 | #7520. Monster Generator | SampsonYW | WA | 1ms | 4000kb | C++14 | 4.3kb | 2024-03-14 16:03:15 | 2024-03-14 16:03:17 |
Judging History
answer
#include <bits/stdc++.h>
#define db double
#define re register
#define il inline
#define ll long long
#define ull unsigned ll
#define i128 __int128
#define pii pair<int, int>
#define fi first
#define se second
#define eb emplace_back
#define SZ(v) (int)v.size()
#define ALL(v) v.begin(), v.end()
#define mems(v, x) memset(v, x, sizeof(v))
#define FOR(i, L, R) for(re int i = (L); i <= (R); ++i)
#define ROF(i, R, L) for(re int i = (R); i >= (L); --i)
#define LS i << 1, l, mid
#define RS i << 1 | 1, mid + 1, r
using namespace std;
#define N 10005
int n; ll m;
ll a[N], ad[N], b[N], bd[N];
i128 A[N], B[N];
struct node {
i128 k, b;
il i128 F(i128 x) {return k * x + b;}
il ull calc(i128 L, i128 R) {
return (ull)k * (ull)((L + R) * (R - L + 1) / 2) + (ull)(R - L + 1) * (ull)b;
}
// il i128 calc(i128 L, i128 R) {
// return k * ((L + R) * (R - L + 1) / 2) + (R - L + 1) * b;
// }
il bool operator < (const node &t) const {return k == t.k ? b < t.b : k < t.k;}
il node operator - (const node &t) const {return {k - t.k, b - t.b};}
il i128 operator * (const node &t) const {return k * t.b - b * t.k;}
} p[N], v[N], h[N];
il bool chk(node A, node B) {return A * B <= 0;}
il i128 calc(i128 lim) {
FOR(i, 0, n) v[i] = p[i];
sort(v, v + n + 1); int top = 0;
FOR(i, 0, n) {
while(top > 1 && chk(v[i] - h[top], h[top] - h[top - 1])) --top;
h[++top] = v[i];
}
// FOR(i, 1, top) cout << (ll)h[i].k << "*x+" << (ll)h[i].b << ", "; cout << "\n";
int now = 0; i128 p = 0, ans = 0;
// FOR(p, 0, lim) {
// i128 s = 0;
// FOR(i, 1, top) s = max(s, h[i].F(p));
// ans += s;
// }
while(p <= lim) {
while(now < top && h[now].F(p) <= h[now + 1].F(p)) ++now;
if(now == top) {ans += h[now].calc(p, lim); break;}
i128 r = p;
ROF(i, 120, 0) {
i128 nr = r + (i128)1 << i; if(nr > lim) continue;
if(h[now].F(nr) > h[now + 1].F(nr)) r = nr;
}
ans += h[now].calc(p, r), ++now, p = r + 1;
}
return ans;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m;
FOR(i, 1, n) cin >> a[i] >> ad[i] >> b[i] >> bd[i];
vector<ll> pos;
FOR(i, 1, n) {
if(a[i] > b[i] && ad[i] < bd[i]) {
ll p = (a[i] - b[i]) / (bd[i] - ad[i]);
pos.eb(p), pos.eb(p + 1);
}
if(a[i] == b[i] && ad[i] != bd[i])
pos.eb(0), pos.eb(1);
if(a[i] < b[i] && ad[i] > bd[i]) {
ll p = (b[i] - a[i]) / (ad[i] - bd[i]);
pos.eb(p), pos.eb(p + 1);
}
}
FOR(i, 1, n) FOR(j, i + 1, n) {
if(a[i] > a[j] && ad[i] < ad[j]) {
ll p = (a[i] - a[j]) / (ad[j] - ad[i]);
pos.eb(p), pos.eb(p + 1);
}
if(a[i] == a[j] && ad[i] != ad[j])
pos.eb(0), pos.eb(1);
if(a[i] < a[j] && ad[i] > ad[j]) {
ll p = (a[j] - a[i]) / (ad[i] - ad[j]);
pos.eb(p), pos.eb(p + 1);
}
if(b[i] > b[j] && bd[i] < bd[j]) {
ll p = (b[i] - b[j]) / (bd[j] - bd[i]);
pos.eb(p), pos.eb(p + 1);
}
if(b[i] == b[j] && bd[i] != bd[j])
pos.eb(0), pos.eb(1);
if(b[i] < b[j] && bd[i] > bd[j]) {
ll p = (b[j] - b[i]) / (bd[i] - bd[j]);
pos.eb(p), pos.eb(p + 1);
}
}
pos.eb(0);
sort(ALL(pos)), pos.erase(unique(ALL(pos)), pos.end());
while(pos.back() > m) pos.pop_back(); pos.eb(m + 1);
i128 ans = 0;
FOR(i, 1, SZ(pos) - 1) {
i128 L = pos[i - 1], R = pos[i] - 1;
FOR(i, 1, n) A[i] = a[i] + L * ad[i], B[i] = b[i] + L * bd[i];
vector<int> Po, Ne;
FOR(i, 1, n) if(A[i] < B[i]) Po.eb(i); else Ne.eb(i);
sort(ALL(Po), [](int x, int y) {return A[x] < A[y];});
sort(ALL(Ne), [](int x, int y) {return B[x] > B[y];});
// for(auto x : Po) cout << x << " "; for(auto x : Ne) cout << x << " "; cout << "\n";
// FOR(i, 1, n) cout << (ll)A[i] << " " << (ll)B[i] << "\n";
int now = 0, pre = 0;
for(auto x : Po) {
++now;
p[now].k = p[now - 1].k + ad[x] - bd[pre];
p[now].b = p[now - 1].b + A[x] - B[pre];
pre = x;
}
for(auto x : Ne) {
++now;
p[now].k = p[now - 1].k + ad[x] - bd[pre];
p[now].b = p[now - 1].b + A[x] - B[pre];
pre = x;
}
// FOR(i, 0, n) cout << (ll)p[i].k << "*x+" << (ll)p[i].b << ", "; cout << "\n";
ans += calc(R - L);
}
cout << (ll)ans;
cerr << 1.0 * clock() / CLOCKS_PER_SEC;
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3908kb
input:
3 5 3 1 5 2 4 2 1 3 1 9 100 1
output:
113
result:
ok single line: '113'
Test #2:
score: 0
Accepted
time: 0ms
memory: 4000kb
input:
3 100000000 3 1 5 2 4 2 1 3 1 9 100 1
output:
35000000549999998
result:
ok single line: '35000000549999998'
Test #3:
score: -100
Wrong Answer
time: 1ms
memory: 3992kb
input:
10 1000000000000000000 776874380544333 197 471391764744275 33 159838820333814 107 677112662750393 41 962335658276824 48 255593531071176 11 127404116579775 209 268525254990127 34 647620110614714 76 897947476313307 13 146196843402516 221 772928712898807 39 637929916804442 2 716937021892338 15 64200226...
output:
50982050797211397
result:
wrong answer 1st lines differ - expected: '17883317185357051350', found: '50982050797211397'