BZOJ 3489: A simple rmq problem KDtree

Code:

#include<bits/stdc++.h>
#define maxn 200000 
#define inf 100000000
#define mid ((l+r)>>1)
#define lson (t[x].ch[0])
#define rson (t[x].ch[1])  
using namespace std;
void setIO(string s)
{
    string in=s+".in"; 
    freopen(in.c_str(),"r",stdin);  
}
int n,Q,lastans,d,_ans; 
int lst[maxn],nex[maxn],pos[maxn],arr[maxn];    
struct Node
{
    int ch[2],minv[3],maxv[3],p[3],w,_max; 
}t[maxn]; 
bool cmp(Node a,Node b)
{
    if(a.p[d]==b.p[d] && a.p[(d+1)%3]==b.p[(d+1)%3]) return a.p[(d+2)%3] < b.p[(d+2)%3]; 
    if(a.p[d]==b.p[d]) return a.p[(d+1)%3] < b.p[(d+1)%3]; 
    return a.p[d] < b.p[d];    
}
void pushup(int x,int y)
{
    for(int i=0;i<3;++i) 
    {
        t[x].minv[i]=min(t[x].minv[i],t[y].minv[i]); 
        t[x].maxv[i]=max(t[x].maxv[i],t[y].maxv[i]);   
    }
    t[x]._max=max(t[x]._max,t[y]._max);        
}
int build(int l,int r,int o)
{
    d=o;   
    nth_element(t+l,t+mid,t+1+r,cmp); 
    for(int i=0;i<3;++i) t[mid].minv[i]=t[mid].maxv[i]=t[mid].p[i];       
    t[mid].ch[0]=t[mid].ch[1]=0; 
    t[mid]._max=t[mid].w;    
    if(mid>l)
    {
        t[mid].ch[0]=build(l,mid-1,(o+1)%3); 
        pushup(mid,t[mid].ch[0]); 
    }
    if(r>mid) 
    {
        t[mid].ch[1]=build(mid+1,r,(o+1)%3); 
        pushup(mid,t[mid].ch[1]); 
    }
    return mid; 
}
int isout(int x,int l,int r)
{
    if(t[x].minv[0] >= l || t[x].maxv[2] <= r || t[x].minv[1] > r || t[x].maxv[1] < l) return 1; 
    return 0; 
}
int isin(int x,int l,int r)
{
    if(t[x].maxv[0] < l && t[x].minv[2] > r && t[x].minv[1] >= l && t[x].maxv[1] <= r) return 1; 
    return 0; 
}
void query(int x,int l,int r)
{
    if(isout(x, l, r)) return; 
    if(isin(x, l, r)) 
    {
        _ans=max(_ans, t[x]._max); 
        return; 
    } 
    if(t[x].p[0] < l && t[x].p[1] >= l && t[x].p[1] <= r && t[x].p[2] > r) _ans=max(_ans, t[x].w); 
    if(lson && t[lson]._max > _ans) query(lson, l, r);  
    if(rson && t[rson]._max > _ans) query(rson, l, r); 
}
int main()
{
    int i,j,x,y,root,a; 
    // setIO("input"); 
    scanf("%d%d",&n,&Q); 
    for(i=1;i<=n;++i)  
    {
        scanf("%d",&a);  
        nex[pos[a]]=i, lst[i]=pos[a], pos[a]=i, arr[i]=a; 
    } 
    for(i=1;i<=n;++i)
    {
        t[i].p[0]=lst[i], t[i].p[1]=i, t[i].p[2] = nex[i] ? nex[i] : n + 1, t[i].w=arr[i];  
    }
    root=build(1,n,0); 
    while(Q--)
    {
        scanf("%d%d",&x,&y); 
        x=(x+lastans) % n + 1; 
        y=(y+lastans) % n + 1; 
        if(x > y) swap(x, y); 
        _ans = -inf; 
        query(root, x, y); 
        lastans = (_ans == -inf ? 0 : _ans); 
        printf("%d\n",lastans); 
    }
    return 0; 
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/11060643.html
今日推荐