zoukankan      html  css  js  c++  java
  • BZOJ 3489: A simple rmq problem KDtree

    Description

    因为是OJ上的题,就简单点好了。给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大。如果找不到这样的数,则直接输出0。我会采取一些措施强制在线。

     

     

    Input

    第一行为两个整数N,MM是询问数,N是序列的长度(N<=100000M<=200000)

    第二行为N个整数,描述这个序列{ai},其中所有1<=ai<=N

    再下面M行,每行两个整数xy

    询问区间[l,r]由下列规则产生(OIER都知道是怎样的吧>_<)

    l=min(x+lastans)mod n+1,(y+lastansmod n+1);

    r=max(x+lastans)mod n+1,(y+lastansmod n+1);

    Lastans表示上一个询问的答案,一开始lastans0

     

    Output

    一共M行,每行给出每个询问的答案。

     题解: 对于一个区间 $[l,r]$ 一个数只出现依次说明上次出现在 $[1,l-1]$ 中(或没出现),下一次出现在 $[r+1,n]$ 中(或没出现).
    直接维护一个 3 维 $KDtree$ 即可.
    第一维维护 $pre_{i}$,第二位维护 $i$ 本身,第三维维护下一次出现的位置.
    每次按照上述条件直接进行数点即可.
    思路还是非常巧妙的.  

    #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
    ",lastans); 
        }
        return 0; 
    }
    

      

  • 相关阅读:
    【React Native】某个页面禁用物理返回键
    【React Native】DeviceEventEmitter监听通知及带参数传值
    转载【React Native代码】手写验证码倒计时组件
    【React Native】 中设置 APP 名称、应用图标、为安卓添加启动图
    【React Native错误集】* What went wrong: Execution failed for task ':app:installDebug'.
    【React Native错误集】Import fails with "Failed to execute 'ImportScripts' on 'WorkerGlobalScope'"
    【React Native错误集】Android error “Could not get BatchedBridge, make sure your bundle is packaged properly” on start of app
    「React Native笔记」在React的 setState 中操作数组和对象的多种方法(合集)
    【React Native】Error: Attribute application@allowBackup value=(false) from AndroidManifest.xml
    坚果云如何使用二次验证码/谷歌身份验证器/两步验证/虚拟MFA?
  • 原文地址:https://www.cnblogs.com/guangheli/p/11060643.html
Copyright © 2011-2022 走看看