[代码]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;
}

 

posted @ 2012-10-17 21:46  杂鱼  阅读(1045)  评论(0编辑  收藏  举报