BZOJ 5052: Busy Financial Officer

For each of the left point, those points can update the answer considering its right
to consider in its right and the value is greater than the current, little can be done after the value flipped over and
that is the left point \ (i \) , find \ (j > i \) satisfies \ (a_j> a_i \)
first find a \ (j \) , the next time \ (j \) to find the right a \ (k \) satisfies \ (a_j> a_k> a_i \
) but such there are still many points to consider trying to find a \ (K \) there are not preferable answers, so also meet the \ (a_j-a_k> a_k-a_i \)
\ (a_k <\ dfrac a_j + {} {a_i 2} \)
thus found \ (a_k \) each at least half, so for each of a left end point \ (I \) number is looking \ (\ log V \) , where \ (V \) represents the value domain
and find \ (j \) as \ (\ log the n-\) , so complexity is \ (O (n \ log v
\ log n) \) so find all points\ ((I, J) \) , the right end of the scan line sweep interrogation process
for each point a single point is taken min and seek min interval
assumed that the current process is a right end point \ (R & lt \) , each query is \ ([L, R & lt] \) , corresponding to \ ([l, n] \ ) a suffix tree can be used to maintain the position of the inverted array

#include <bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define pii pair<int, int>
#define lp p << 1
#define rp p << 1 | 1
#define mid ((l + r) >> 1)
#define ll long long
#define db double
#define rep(i,a,b) for(int i=a;i<b;i++)
#define per(i,a,b) for(int i=b-1;i>=a;i--)
#define Edg int ccnt=1,head[N],to[N*2],ne[N*2];void addd(int u,int v){to[++ccnt]=v;ne[ccnt]=head[u];head[u]=ccnt;}void add(int u,int v){addd(u,v);addd(v,u);}
#define Edgc int ccnt=1,head[N],to[N*2],ne[N*2],c[N*2];void addd(int u,int v,int w){to[++ccnt]=v;ne[ccnt]=head[u];c[ccnt]=w;head[u]=ccnt;}void add(int u,int v,int w){addd(u,v,w);addd(v,u,w);}
#define es(u,i,v) for(int i=head[u],v=to[i];i;i=ne[i],v=to[i])
const int MOD = 1e9 + 7;
void M(int &x) {if (x >= MOD)x -= MOD; if (x < 0)x += MOD;}
int qp(int a, int b = MOD - 2) {int ans = 1; for (; b; a = 1LL * a * a % MOD, b >>= 1)if (b & 1)ans = 1LL * ans * a % MOD; return ans % MOD;}
int gcd(int a, int b) { while (b) { a %= b; std::swap(a, b); } return a; }
char buf[1 << 21], *p1 = buf, *p2 = buf;
inline char getc() {
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
inline int _() {
    int x = 0, f = 1; char ch = getc();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getc(); }
    while (ch >= '0' && ch <= '9') { x = x * 10ll + ch - 48; ch = getc(); }
    return x * f;
}

const int N = 1e5 + 7;
const int INF = 0x3f3f3f3f;
int n, m, a[N], b[N], mn[N << 2], ans[N];
std::vector<std::pii> vec[N];
inline bool cmp(int x, int y) {
    return a[x] == a[y] ? x > y : a[x] > a[y];
}
void update(int p, int l, int r, int pos, int v) {
    mn[p] = std::min(mn[p], v);
    if (l == r) return;
    if (pos <= mid) update(lp, l, mid, pos, v);
    else update(rp, mid + 1, r, pos, v);
}
int query(int p, int l, int r, int pos, int v) {
    if (mn[p] > v) return 0;
    if (l == r) return l;
    if (pos <= mid) {
        int t = query(lp, l, mid, pos, v);
        if (t) return t;
    }
    return query(rp, mid + 1, r, pos, v);
}

struct QUERY {
    int l, r, id;
    bool operator < (const QUERY &p) const {
        return r < p.r;
    }
} Q[N];

void init() {
    std::sort(b + 1, b + 1 + n, cmp);
    memset(mn, 0x3f, sizeof(mn));
    rep (i, 1, n + 1) {
        int j = query(1, 1, n, b[i], INF - 1);
        while (j) {
            vec[j].pb(std::pii(b[i], a[j] - a[b[i]]));
            j = query(1, 1, n, b[i], (a[b[i]] + a[j] - 1) / 2);
        }
        update(1, 1, n, b[i], a[b[i]]);
    }
}
struct BIT {
    int tree[N];
    BIT() { memset(tree, 0x3f, sizeof(tree)); }
    inline int lowbit(int x) { return x & -x; }
    void add(int x, int v) {
        x = n - x + 1;
        for (int i = x; i <= n; i += lowbit(i))
            tree[i] = std::min(tree[i], v);
    }
    int query(int x) {
        x = n - x + 1;
        int ans = INF;
        for (int i = x; i; i -= lowbit(i))
            ans = std::min(ans, tree[i]);
        return ans;
    }
} bit;

int main() {
    n = _(), m = _();
    rep (i, 1, n + 1) a[i] = _(), b[i] = i;
    init();
    rep (i, 1, n + 1) a[i] = 1e9 - a[i] + 1;
    init();
    rep (i, 0, m) Q[i].l = _(), Q[i].r = _(), Q[i].id = i;
    std::sort(Q, Q + m);
    int cur = 1;
    rep (i, 0, m) {
        while (cur <= Q[i].r) {
            rep (j, 0, vec[cur].size()) bit.add(vec[cur][j].fi, vec[cur][j].se);
            cur++;
        }
        ans[Q[i].id] = bit.query(Q[i].l);
    }
    rep (i, 0, m) printf("%d\n", ans[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/Mrzdtz220/p/12360854.html