题解 P4269 【[USACO18FEB]Snow Boots G】

· · 题解

代码实现(c++):

#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN=110000;
struct SegmentTree
{
    #define lc (root<<1)
    #define rc (root<<1|1)
    struct Node
    {
        bool val;
        int len, maxx, maxl, maxr;
    } tr[MAXN*4];
    void pushup(int root) // 维护区间信息
    {
        tr[root].len=tr[lc].len+tr[rc].len;
        tr[root].maxx=tr[root].maxl=tr[root].maxr=tr[root].val;
        tr[root].maxl=max(tr[root].maxl, tr[lc].maxl);
        if (tr[lc].maxx==tr[lc].len)
            tr[root].maxl=max(tr[root].maxl, tr[lc].len+tr[rc].maxl);
        tr[root].maxr=max(tr[root].maxr, tr[rc].maxr);
        if (tr[rc].maxx==tr[rc].len)
            tr[root].maxr=max(tr[root].maxr, tr[rc].len+tr[lc].maxr);
        tr[root].maxx=max(tr[root].maxx, tr[lc].maxx);
        tr[root].maxx=max(tr[root].maxx, tr[rc].maxx);
        tr[root].maxx=max(tr[root].maxx, tr[lc].maxr+tr[rc].maxl);
    }
    void update(int root, int l, int r, int x) // 单点修改
    {
        if (l==r)
        {
            tr[root].maxx=tr[root].maxl=tr[root].maxr=tr[root].val=0;
            return;
        }
        int mid=l+r>>1;
        if (x<=mid) update(lc, l, mid, x);
        else update(rc, mid+1, r, x);
        pushup(root);
    }
    int query() // 查询
    {
        return tr[1].maxx; // 1 就是树根结点,维护了整个区间
    }
    void build(int root, int l, int r)
    {
        tr[root].val=0;
        if (l==r)
        {
            tr[root].len=1;
            tr[root].maxx=tr[root].maxl=tr[root].maxr=tr[root].val=1;
            return;
        }
        int mid=l+r>>1;
        build(lc, l, mid);
        build(rc, mid+1, r);
        pushup(root);
    }
    #undef lc
    #undef rc
} st;
struct Snow // 这里定义了一个结构体用来排序时记录下标
{
    int id, step, dep;
    bool operator < (const Snow& rhs) const
    {
        return dep!=rhs.dep?dep<rhs.dep:step<rhs.step;
    }
    Snow(int i=0, int s=0, int d=0):
        id(i), step(s), dep(d) {}
} a[MAXN*2];
int n, m;
bool ans[MAXN];
int main()
{
    freopen("snowboots.in", "r", stdin);
    freopen("snowboots.out", "w", stdout);
    scanf("%d%d", &n, &m);
    for (int i=1, f; i<=n; i++)
    {
        scanf("%d", &f);
        a[i]=Snow(i, 0, f);
    }
    for (int i=1, s, d; i<=m; i++)
    {
        scanf("%d%d", &s, &d);
        a[i+n]=Snow(i, d, s);
    }
    sort(a+1, a+n+m+1);
    st.build(1, 1, n);
    for (int i=1; i<=n+m; i++)
    {
        if (a[i].step==0) st.update(1, 1, n, a[i].id);
        else ans[a[i].id]=st.query()<a[i].step;
    }
    for (int i=1; i<=m; i++) printf("%d\n", ans[i]);
    return 0;
}