제출 #224740

#제출 시각아이디문제언어결과실행 시간메모리
224740BruteforcemanBulldozer (JOI17_bulldozer)C++11
100 / 100
1835 ms79448 KiB
#include <bits/stdc++.h>
using namespace std;
using pii = pair <int, int>;
const int maxn = 2005;
struct point {
  long long x, y, w;
  point () {}
  point (long long x, long long y) : x(x), y(y) {}
  point operator - (point p) {
    return point(x - p.x, y - p.y);
  }
  point operator + (point p) {
    return point(x + p.x, y + p.y);
  }
  point normalize() {
    long long d = __gcd(abs(x), abs(y));
    if(d == 0) return *this;
    else return point(x / d, y / d);
  }
} a[maxn];
long long dot(point p, point q) { return p.x*q.x + p.y*q.y; }
long long cross(point p, point q) { return p.x*q.y - q.x*p.y; }
bool operator < (point p, point q) {
  return cross(p, q) > 0;
}
long long dist(point p) { return dot(p, p); }

bool vis[maxn];
int n;
int cost[maxn];
int pos[maxn], c[maxn];

struct data {
  long long sum, opt, pre, suf;
} t[maxn * 4];
struct info {
    point p;
    int i, j;
    info (point p, int i, int j) : p(p), i(i), j(j) {}
    info () {}
    bool operator < (info x) const {
        if(!cross(p, x.p)) {
            return dist(a[i] - a[j]) > dist(a[x.i] - a[x.j]);
        }
        return p < x.p; 
    }
};

data merge(data p, data q) {
  data x;
  x.sum = p.sum + q.sum;
  x.pre = max(p.pre, p.sum + q.pre);
  x.suf = max(q.suf, q.sum + p.suf);
  x.opt = max(p.opt, q.opt);
  x.opt = max(x.opt, p.suf + q.pre);
  return x;
}
void update(int x, int val, int c = 1, int b = 1, int e = n) {
  if(b == e) {
    t[c].sum = val;
    t[c].pre = t[c].suf = t[c].opt = max(0, val);
    return ;
  }
  int m = (b + e) >> 1;
  int l = c << 1;
  int r = l + 1;
  if(x <= m) update(x, val, l, b, m);
  else update(x, val, r, m + 1, e);
  t[c] = merge(t[l], t[r]);
}
long long maxSubarray() {
  return t[1].opt;
}
int main() {
  ios_base :: sync_with_stdio (false);
  cin.tie(0);

  cin >> n;
  long long ans = 0;
  for(int i = 1; i <= n; i++) {
    cin >> a[i].x >> a[i].y >> a[i].w;
    ans = max(ans, a[i].w);
  }
  sort(a + 1, a + n + 1, [&] (point p, point q) {
      return make_pair(p.y, p.x) < make_pair(q.y, q.x);  });

  vector <info> can;
  for(int i = 1; i <= n; i++) {
    for(int j = i + 1; j <= n; j++) {
      point p = a[j] - a[i];
      p = p.normalize();
      can.emplace_back(p, i, j);
    }
  }
  for(int i = 1; i <= n; i++) {
    pos[i] = i;
    c[i] = i;
    cost[i] = a[i].w;
    update(i, cost[i]);
  }
  sort(can.begin(), can.end());
  int now = 0;
  while(now < can.size()) {
    vector <pair <int, int>> v;
    do {
        v.emplace_back(can[now].i, can[now].j);
        ++now;
    } while (now < can.size() && cross(can[now - 1].p, can[now].p) == 0);
    vector <pii> affected;
    for(auto j : v) {
      if(vis[pos[j.first]]) continue;
      for(int k = pos[j.first]; k <= pos[j.second]; k++) {
        vis[k] = true;
      }
      affected.emplace_back(pos[j.first], pos[j.second]);
    }
    ans = max(ans, maxSubarray());
    for(auto j : affected) {
      reverse(c + j.first, c + j.second + 1);
      for(int k = j.first; k <= j.second; k++) {
        vis[k] = false;
        pos[c[k]] = k;
        cost[k] = a[c[k]].w;
        update(k, cost[k]);
      }
    }
  }
  cout << ans << endl;
  return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

bulldozer.cpp: In function 'int main()':
bulldozer.cpp:103:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   while(now < can.size()) {
         ~~~~^~~~~~~~~~~~
bulldozer.cpp:108:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     } while (now < can.size() && cross(can[now - 1].p, can[now].p) == 0);
              ~~~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...