QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#198186 | #7520. Monster Generator | hos_lyric | WA | 1ms | 3716kb | C++14 | 7.5kb | 2023-10-03 08:53:31 | 2023-11-04 18:37:19 |
Judging History
你现在查看的是最新测评结果
- [2023-11-04 16:34:13]
- hack成功,自动添加数据
- (//qoj.ac/hack/422)
- [2023-11-04 16:28:16]
- hack成功,自动添加数据
- (//qoj.ac/hack/420)
- [2023-10-03 08:53:31]
- 提交
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; }
#define COLOR(s) ("\x1b[" s "m")
#ifndef LIBRA_OTHER_INT128_H_
#define LIBRA_OTHER_INT128_H_
#include <stdio.h>
#include <iostream>
constexpr unsigned __int128 toUInt128(const char *s) {
unsigned __int128 x = 0;
for (; *s; ++s) x = x * 10 + (*s - '0');
return x;
}
constexpr __int128 toInt128(const char *s) {
if (*s == '-') return -toInt128(s + 1);
__int128 x = 0;
for (; *s; ++s) x = x * 10 + (*s - '0');
return x;
}
unsigned __int128 inUInt128() {
static char buf[41];
scanf("%s", buf);
return toUInt128(buf);
}
__int128 inInt128() {
static char buf[41];
scanf("%s", buf);
return toInt128(buf);
}
void out(unsigned __int128 x) {
static char buf[41];
int len = 0;
do { buf[len++] = '0' + static_cast<int>(x % 10); } while (x /= 10);
for (int i = len; --i >= 0; ) putchar(buf[i]);
}
void out(__int128 x) {
if (x < 0) {
putchar('-');
out(-static_cast<unsigned __int128>(x));
} else {
out(static_cast<unsigned __int128>(x));
}
}
std::ostream &operator<<(std::ostream &os, unsigned __int128 x) {
static char buf[41];
int len = 0;
do { buf[len++] = '0' + static_cast<int>(x % 10); } while (x /= 10);
for (int i = len; --i >= 0; ) os << buf[i];
return os;
}
std::ostream &operator<<(std::ostream &os, __int128 x) {
if (x < 0) {
os << '-' << -static_cast<unsigned __int128>(x);
} else {
os << static_cast<unsigned __int128>(x);
}
return os;
}
#endif // LIBRA_OTHER_INT128_H_
// -first +second
namespace downup {
template <class T> bool cmp(const pair<T, T> &a, const pair<T, T> &b) {
return (a.first <= a.second)
? ((b.first <= b.second) ? (a.first < b.first) : true)
: ((b.first <= b.second) ? false : (a.second > b.second));
}
template <class T> pair<T, T> merge(const pair<T, T> &a, const pair<T, T> &b) {
return (a.second >= b.first)
? make_pair(a.first, a.second - b.first + b.second)
: make_pair(a.first - a.second + b.first, b.second);
}
} // downup
using Int = __int128;
// floor(a / b)
Int divFloor(Int a, Int b) {
return a / b - (((a ^ b) < 0 && a % b != 0) ? 1 : 0);
}
// ceil(a / b)
Int divCeil(Int a, Int b) {
return a / b + (((a ^ b) > 0 && a % b != 0) ? 1 : 0);
}
using U = unsigned long long;
int N;
Int M;
vector<Int> A, P, B, Q;
int main() {
for (; ~scanf("%d", &N); ) {
M = inInt128();
A.resize(N);
P.resize(N);
B.resize(N);
Q.resize(N);
for (int i = 0; i < N; ++i) {
A[i] = inInt128();
P[i] = inInt128();
B[i] = inInt128();
Q[i] = inInt128();
}
vector<Int> xs;
xs.push_back(0);
xs.push_back(M + 1);
auto add = [&](Int x) -> void {
if (0 <= x && x <= M + 1) {
xs.push_back(x);
}
};
auto check = [&](Int a, Int p, Int b, Int q, bool careful) -> void {
if (p != q) {
const Int x0 = divFloor(a - b, q - p);
const Int x1 = divCeil(a - b, q - p);
if (x0 < x1) {
add(x1);
} else if (careful) {
add(x1);
add(x1 + 1);
}
}
};
for (int i = 0; i < N; ++i) {
check(A[i], P[i], B[i], Q[i], true);
}
for (int i = 0; i < N; ++i) for (int j = i + 1; j < N; ++j) {
check(A[i], P[i], A[j], P[j], false);
check(B[i], Q[i], B[j], Q[j], false);
}
sort(xs.begin(), xs.end());
xs.erase(unique(xs.begin(), xs.end()), xs.end());
// cerr<<"xs = "<<xs<<endl;
U ans = 0;
for (int h = 0; h < (int)xs.size() - 1; ++h) {
const Int xL = xs[h];
const Int xR = xs[h + 1];
using Entry = pair<pair<Int, Int>, int>;
vector<Entry> es(N);
for (int i = 0; i < N; ++i) {
es[i] = make_pair(make_pair(A[i] + P[i] * xL, B[i] + Q[i] * xL), i);
}
sort(es.begin(), es.end(), [&](const Entry &e0, const Entry &e1) -> bool {
return downup::cmp(e0.first, e1.first);
});
vector<pair<Int, Int>> ps;
Int c = 0, r = 0;
for (const Entry &e : es) {
const int i = e.second;
c -= A[i]; r -= P[i];
ps.emplace_back(-c, -r);
c += B[i]; r += Q[i];
}
for (auto &p : ps) swap(p.first, p.second);
sort(ps.begin(), ps.end());
for (auto &p : ps) swap(p.first, p.second);
int qsLen = 0;
vector<pair<Int, Int>> qs(ps.size());
for (int k = 0; k < (int)ps.size(); ++k) {
if (k + 1 < (int)ps.size() && ps[k].second == ps[k + 1].second) continue;
const auto &p = ps[k];
for (; qsLen >= 2; --qsLen) {
const auto &q2 = qs[qsLen - 2];
const auto &q1 = qs[qsLen - 1];
if ((q2.first - q1.first) * (p.second - q1.second) < (q1.first - p.first) * (q1.second - q2.second)) {
break;
}
}
qs[qsLen++] = p;
}
qs.resize(qsLen);
vector<Int> cut(qsLen - 1);
for (int k = 0; k < qsLen - 1; ++k) {
cut[k] = divCeil(qs[k].first - qs[k + 1].first, qs[k + 1].second - qs[k].second);
}
U sum = 0;
for (int k = 0; k < qsLen; ++k) {
Int x0 = xL, x1 = xR;
if (k > 0) chmax(x0, cut[k - 1]);
if (k < qsLen - 1) chmin(x1, cut[k]);
if (x0 < x1) {
sum += (U)qs[k].first * (U)(x1 - x0);
Int t0 = x1 - x0;
Int t1 = x0 + x1 - 1;
(t0 % 2 == 0) ? (t0 /= 2) : (t1 /= 2);
sum += (U)qs[k].second * (U)t0 * (U)t1;
}
}
ans += sum;
#ifdef LOCAL
cerr<<"["<<xL<<", "<<xR<<"): ps = "<<ps<<", qs = "<<qs<<endl;
if(M<=1'000'000){
Int brt=0;
for(Int x=xL;x<xR;++x){
Int mx=0;
for(const auto &p:ps)chmax(mx,p.first+p.second*x);
cerr<<x<<": "<<mx<<endl;
brt+=mx;
}
if(brt!=sum)cerr<<"brt = "<<brt<<", sum = "<<sum<<endl;
assert(brt==sum);
}
#endif
}
printf("%llu\n", ans);
#ifdef LOCAL
if(M<=1'000'000){
Int brt=0;
for(Int x=0;x<=M;++x){
vector<pair<Int,Int>>fs(N);
for(int i=0;i<N;++i)fs[i]=make_pair(A[i]+P[i]*x,B[i]+Q[i]*x);
sort(fs.begin(),fs.end(),downup::cmp<Int>);
Int mx=0;
Int now=0;
for(const auto&f:fs){
now-=f.first;
chmax(mx,-now);
now+=f.second;
}
cerr<<x<<": "<<mx<<endl;
brt+=mx;
}
if(brt!=ans)cerr<<"brt = "<<brt<<", ans = "<<ans<<endl;
assert(brt==ans);
}
#endif
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 3716kb
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: 1ms
memory: 3684kb
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: 0
Accepted
time: 1ms
memory: 3680kb
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:
17883317185357051350
result:
ok single line: '17883317185357051350'
Test #4:
score: -100
Wrong Answer
time: 0ms
memory: 3708kb
input:
10 1000000000000 519946 5 967590 4 367668 9 772494 6 635694 5 932710 1 260259 2 627580 1 84994 3 52124 6 447095 4 705749 6 427312 2 977458 7 540121 1 292993 5 556831 6 321679 4 567919 4 609512 4
output:
1542003557143376326
result:
wrong answer 1st lines differ - expected: '1542003553318518337', found: '1542003557143376326'