QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#198179#7520. Monster Generatorhos_lyricWA 1ms3712kbC++147.4kb2023-10-03 08:47:332023-10-03 08:47:34

Judging History

你现在查看的是测评时间为 2023-10-03 08:47:34 的历史记录

  • [2023-11-04 18:37:18]
  • 管理员手动重测本题所有提交记录
  • 测评结果:WA
  • 用时:0ms
  • 内存:4080kb
  • [2023-11-04 17:11:22]
  • 管理员手动重测本题所有提交记录
  • 测评结果:0
  • 用时:1ms
  • 内存:3720kb
  • [2023-10-03 08:47:34]
  • 评测
  • 测评结果:0
  • 用时:1ms
  • 内存:3712kb
  • [2023-10-03 08:47:33]
  • 提交

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 check = [&](Int a, Int p, Int b, Int q, bool careful) -> void {
      if (p != q) {
        {
          const Int x = divCeil(a - b, q - p);
          if (0 <= x && x <= M + 1) xs.push_back(x);
        }
        if (careful) {
          const Int x = divFloor(a - b, q - p) + 1;
          if (0 <= x && x <= M + 1) xs.push_back(x);
        }
      }
    };
    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: 3624kb

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: 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: 0ms
memory: 3708kb

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: 3712kb

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:

1542003553990367833

result:

wrong answer 1st lines differ - expected: '1542003553318518337', found: '1542003553990367833'