結果
問題 | No.511 落ちゲー 〜手作業のぬくもり〜 |
ユーザー |
![]() |
提出日時 | 2018-04-06 19:30:27 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 99 ms / 4,000 ms |
コード長 | 5,241 bytes |
コンパイル時間 | 1,995 ms |
コンパイル使用メモリ | 187,616 KB |
実行使用メモリ | 11,604 KB |
最終ジャッジ日時 | 2024-11-24 12:42:04 |
合計ジャッジ時間 | 3,789 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 5 |
other | AC * 32 |
ソースコード
#include "bits/stdc++.h"using namespace std;#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))#define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))#define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))static const int INF = 0x3f3f3f3f; static const long long INFL = 0x3f3f3f3f3f3f3f3fLL;typedef vector<int> vi; typedef pair<int, int> pii; typedef vector<pair<int, int> > vpii; typedef long long ll;template<typename T, typename U> static void amin(T &x, U y) { if (y < x) x = y; }template<typename T, typename U> static void amax(T &x, U y) { if (x < y) x = y; }using Val = ll;const Val infVal = INFL;struct Sum {int num;Val minVal;Sum() : num(0), minVal(infVal) {}Sum(const Val &val, int pos) : num(val == infVal ? 0 : 1), minVal(val) { }Sum &operator+=(const Sum &that) {num += that.num;amin(minVal, that.minVal);return *this;}Sum operator+(const Sum &that) const { return Sum(*this) += that; }};struct Add {ll sub;Add() : sub(0) { }Add &operator+=(const Add &that) { sub += that.sub; return *this; }void addToVal(Val &val, int pos) const { if (val != infVal) val -= sub; }void addToSum(Sum &sum, int left, int right) const {if (sum.minVal != infVal)sum.minVal -= sub;}};struct SegmentTree {vector<Val> leafs;vector<Sum> nodes;vector<Add> add;vector<int> leftpos, rightpos;int n, n2;void init(int n_, const Val &v = Val()) { init(vector<Val>(n_, v)); }void init(const vector<Val> &u) {n = 1; while (n < (int)u.size()) n *= 2;n2 = (n - 1) / 2 + 1;leafs = u; leafs.resize(n, Val());nodes.resize(n);for (int i = n - 1; i >= n2; -- i)nodes[i] = Sum(leafs[i * 2 - n], i * 2 - n) + Sum(leafs[i * 2 + 1 - n], i * 2 + 1 - n);for (int i = n2 - 1; i > 0; -- i)nodes[i] = nodes[i * 2] + nodes[i * 2 + 1];add.assign(n, Add());leftpos.resize(n); rightpos.resize(n);for (int i = n - 1; i >= n2; -- i) {leftpos[i] = i * 2 - n;rightpos[i] = (i * 2 + 1 - n) + 1;}for (int i = n2 - 1; i > 0; -- i) {leftpos[i] = leftpos[i * 2];rightpos[i] = rightpos[i * 2 + 1];}}Val get(int i) {int indices[128];int k = getIndices(indices, i, i + 1);propagateRange(indices, k);return leafs[i];}Sum getRangeCommutative(int i, int j) {int indices[128];int k = getIndices(indices, i, j);propagateRange(indices, k);Sum res = Sum();for (int l = i + n, r = j + n; l < r; l >>= 1, r >>= 1) {if (l & 1) res += sum(l ++);if (r & 1) res += sum(-- r);}return res;}void set(int i, const Val &x) {int indices[128];int k = getIndices(indices, i, i + 1);propagateRange(indices, k);leafs[i] = x;mergeRange(indices, k);}void addToRange(int i, int j, const Add &x) {if (i >= j) return;int indices[128];int k = getIndices(indices, i, j);propagateRange(indices, k);int l = i + n, r = j + n;if (l & 1) { int p = (l ++) - n; x.addToVal(leafs[p], p); }if (r & 1) { int p = (-- r) - n; x.addToVal(leafs[p], p); }for (l >>= 1, r >>= 1; l < r; l >>= 1, r >>= 1) {if (l & 1) add[l ++] += x;if (r & 1) add[-- r] += x;}mergeRange(indices, k);}private:int getIndices(int indices[], int i, int j) const {int k = 0, l, r;if (i >= j) return 0;for (l = (n + i) >> 1, r = (n + j - 1) >> 1; l != r; l >>= 1, r >>= 1) {indices[k ++] = l;indices[k ++] = r;}for (; l; l >>= 1) indices[k ++] = l;return k;}void propagateRange(int indices[], int k) {for (int i = k - 1; i >= 0; -- i)propagate(indices[i]);}void mergeRange(int indices[], int k) {for (int i = 0; i < k; ++ i)merge(indices[i]);}inline void propagate(int i) {if (i >= n) return;add[i].addToSum(nodes[i], leftpos[i], rightpos[i]);if (i * 2 < n) {add[i * 2] += add[i];add[i * 2 + 1] += add[i];} else {add[i].addToVal(leafs[i * 2 - n], i * 2 - n);add[i].addToVal(leafs[i * 2 + 1 - n], i * 2 + 1 - n);}add[i] = Add();}inline void merge(int i) {if (i >= n) return;nodes[i] = sum(i * 2) + sum(i * 2 + 1);}inline Sum sum(int i) {propagate(i);return i < n ? nodes[i] : Sum(leafs[i - n], i - n);}public:void searchAndSetInf(int i, int j, vector<pair<int, Val>> &out) {searchAndSetInfAllRec(1, i, j, out);}private:void searchAndSetInfAllRec(int i, int l, int r, vector<pair<int, Val>> &out) {propagate(i);if (sum(i).minVal > 0) return;if (i >= n) {if (l <= i - n && i - n < r) {out.emplace_back(i - n, leafs[i - n]);leafs[i - n] = infVal;}return;}amax(l, leftpos[i]);amin(r, rightpos[i]);if (l >= r) return;searchAndSetInfAllRec(i * 2, l, r, out);searchAndSetInfAllRec(i * 2 + 1, l, r, out);merge(i);}};int main() {int N; int W; long long H;while (~scanf("%d%d%lld", &N, &W, &H)) {SegmentTree segt;segt.init(W, Val(H));vector<pair<int, Val>> tmp;array<int, 2> score = {0, 0};rep(i, N) {int a; long long b; int x;scanf("%d%lld%d", &a, &b, &x), -- x;Add add;add.sub = b;segt.addToRange(x, x + a, add);tmp.clear();segt.searchAndSetInf(x, x + a, tmp);score[i % 2] += (int)tmp.size();}puts(score[0] > score[1] ? "A" : score[0] < score[1] ? "B" : "DRAW");}return 0;}