BZOJ 3489 A simple rmq problem

来源:互联网 发布:千锋 育知同创 编辑:程序博客网 时间:2024/05/18 13:44

可持久化树套树

发现这是一个多维偏序,可持久化树套树即可。

#include<cstdio>#include<algorithm> #define N 100005using namespace std;namespace runzhe2000{    int read()    {        int r = 0; char c = getchar();        for(; c < '0' || c > '9'; c = getchar());        for(; c >='0' && c <='9'; r = r*10+c-'0', c = getchar());        return r;    }    int n, m, a[N], lastvis[N], pre[N], next[N], end[N], rk[N];    struct seg0    {        seg0 *ch[2]; int v;    }mem0[N*350], *tot0, *null0;    int query0(seg0 *x, int l, int r, int ql, int qr)    {        if(ql <= l && r <= qr) return x->v; int mid = (l+r)>>1, ret = 0;        if(ql <= mid) ret = max(ret, query0(x->ch[0], l,mid,ql,qr));        if(mid <  qr) ret = max(ret, query0(x->ch[1], mid+1,r,ql,qr));        return ret;    }    void modi0(seg0 *x, seg0 *y, int l, int r, int p, int val)    {        x->v = max(x->v, val);  if(l == r){ return;} int mid = (l+r)>>1;        if(p <= mid)         {            seg0 *tmp = ++tot0; *tmp = *y->ch[0];            modi0(tmp,y->ch[0],l,mid,p,val);            x->ch[0] = tmp;        }        else         {            seg0 *tmp = ++tot0; *tmp = *y->ch[1];            modi0(tmp,y->ch[1], mid+1,r,p,val);            x->ch[1] = tmp;        }    }    struct seg1    {        seg1 *ch[2]; seg0 *v;    }mem1[N*40], *tot1, *root[N], *null1;    int query1(seg1 *x, int l, int r, int ql, int qr, int qql, int qqr)    {        if(ql <= l && r <= qr) return query0(x->v,0,n+1,qql,qqr); int mid = (l+r)>>1, ret = 0;        if(ql <= mid) ret = max(ret, query1(x->ch[0], l,mid,ql,qr,qql,qqr));        if(mid <  qr) ret = max(ret, query1(x->ch[1], mid+1,r,ql,qr,qql,qqr));        return ret;    }    void modi1(seg1 *x, seg1 *y, int l, int r, int p, int p2, int val)    {        seg0 *tmp = ++tot0; *tmp = *y->v;        modi0(tmp, y->v, 0, n+1, p2, val);        x->v = tmp;        if(l == r) return; int mid = (l+r)>>1;        if(p <= mid)         {            seg1 *tmp = ++tot1; *tmp = *y->ch[0];            modi1(tmp,y->ch[0],l,mid,p,p2,val);            x->ch[0] = tmp;        }        else         {            seg1 *tmp = ++tot1; *tmp = *y->ch[1];            modi1(tmp,y->ch[1], mid+1,r,p,p2,val);            x->ch[1] = tmp;        }    }    void init()    {        null0 = tot0 = mem0; null0->ch[0] = null0->ch[1] = null0; null0->v = 0;        null1 = tot1 = mem1; null1->ch[0] = null1->ch[1] = null1; null1->v = null0;        root[0] = null1;    }    bool cmp(int a, int b){return pre[a] < pre[b];}    void main()    {        n = read(), m = read();        for(int i = 1; i <= n; i++)         {            pre[i] = lastvis[a[i] = read()];            lastvis[a[i]] = i;        }        for(int i = 1; i <= n; i++) lastvis[a[i]] = n+1;        for(int i = n; i; i--)        {            next[i] = lastvis[a[i]];            lastvis[a[i]] = i;            rk[i] = i;        }        init(); sort(rk+1, rk+1+n, cmp);        for(int i = 1; i <= n; i++)        {            root[i] = ++tot1, *root[i] = *root[i-1]; end[pre[rk[i]]] = i;            modi1(root[i], root[i-1], 0, n+1, next[rk[i]], rk[i], a[rk[i]]);        }        for(int i = 1; i <= n; i++) end[i] = max(end[i], end[i-1]);        int ans = 0, x, y, l, r;        for(int i = 1; i <= m; i++)        {            x = read(), y = read();            l = min((x+ans)%n+1, (y+ans)%n+1);            r = max((x+ans)%n+1, (y+ans)%n+1);            printf("%d\n",ans = query1(root[end[l-1]],0,n+1,r+1,n+1,l,r));        }    }}int main(){    runzhe2000::main();}
0 0
原创粉丝点击