[代码]ACM-ICPC 2012 Regionals Asia - Changchun A Alice and Bob / ZJU 3655
Abstract
ZJU 3655 Alice and Bob
乱搞 离散化 implementation
Body
Source
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3655
Description
才不告诉你呢自己看去>_<
Solution
显然,Alice最后可以拿到a-b个。考虑对于Alice的某个决策区间(长度为a),Bob一定会选择其中一个长度为a-b的区间,使得区间内的白球个数最少。
所以这实质上就是个RMQ问题找区间最小值。由于需要处理的区间很多,所以需要离散化,只留下那些本质不同的区间。
至于离散化的过程就是恶心又tricky的implementation……
Code
即使你注意到R-L+1爆long long而启用unsigned long long,也还是要各种小心,少用减法,步步为营……
我是4Y的……给1Y的bluemary跪了……
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; #define fr first #define sc second #define L(x) (x<<1) #define R(x) (x<<1|1) #define M(x) (x>>1) typedef unsigned long long ll; typedef pair<ll, int> pr; pr (*mkpr)(ll, int) = make_pair<ll, int>; int N, M; ll l, r, a, b, c; ll p[111111]; deque<ll> q; vector<pr> node; struct st { int l, r, v; }t[222222<<2]; void pushup(int n) { t[n].v = min(t[L(n)].v, t[R(n)].v); } void build(int l, int r, int n) { t[n].l = l, t[n].r = r; if (l==r) { t[n].v = node[l].sc; return; } int m = M(l+r); build(l, m, L(n)); build(m+1, r, R(n)); pushup(n); } int query(int l, int r, int n) { if (l<=t[n].l && r>=t[n].r) return t[n].v; int res = 0x3fffffff; int m = M(t[n].l+t[n].r); if (l<=m) res = min(res, query(l, r, L(n))); if (r>m) res = min(res, query(l, r, R(n))); return res; } int bs(ll x) { int l = 0, r = M-1, m; while (l<r) { m = l+r+1>>1; if (node[m].fr<=x) l = m; else r = m-1; } return l; } int main() { int i, j, k; ll now; while (cin>>N) { cin>>l>>r>>a>>b; c = a-b; for (i = 0; i < N; ++i) scanf("%llu", p+i); if (a==b) { puts("0"); continue; } i = 0; now = l+c-1; node.clear(); q.clear(); while (now <= r) { while (i<N && p[i]<=now) q.push_back(p[i++]); while (!q.empty() && q.front()+c<=now) q.pop_front(); node.push_back(mkpr(now, (int)q.size())); if (i==N && q.empty()) break; ll add = i<N ? p[i]-now : INF; ll del = q.empty() ? INF : q.front()+c-now; now += min(add, del); } if (node.size()==0) { puts("0"); continue; } M = node.size(); build(0, M-1, 1); int ans = 0; for (i = 0; i < M; ++i) { ll up = node[i].fr+b; if (up>r) continue; j = bs(up); if (i<=j) ans = max(ans, query(i, j, 1)); } for (i = 0; i < M; ++i) { if (node[i].fr+1<l+a) continue; ll down = node[i].fr-b; j = bs(down); if (j<=i) ans = max(ans, query(j, i, 1)); } printf("%d\n", ans); } return 0; }