zoukankan      html  css  js  c++  java
  • 【kd-tree】bzoj3489 A simple rmq problem

    Orz zyf教给蒟蒻做法

      蒟蒻并不会这题正解……(可持久化树套树?。。。Orz

      对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]),其中 i 满足(pre[i]<ql and nex[i]>qr and i[ql,qr])

      然后我们以(i,pre[i],nex[i])为坐标……将所有点抽象到三维空间中,每次查询就相当于是一次区域求最值!

    这题我的感受:

    因为前面做了两道区域求和的……然后思路不由自主又代入到搞【子树最大值】来更新答案……然而忘记了单点更新,也就是:虽然这个子树不合法,但是这一个点(根)还是可能合法的……

    然后就是:KD-Tree如果可以搞整个子树的话,那么用整个子树的最值去更新,会优化很多……?

    终于1A了一道KD-Tree啦~好开心(虽然不是自己想出的做法……)

    ——http://www.cnblogs.com/Tunix/p/4522925.html

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define N 100001
    #define INF 2147483647
    #define KD 3//ά¶ÈÊý
    int qp[2];
    int n,root,m;
    int dn;
    struct Node
    {
        int minn[KD],maxx[KD],p[KD],w,maxv;
        int ch[2];
        void Init()
          {
            for(int i=0;i<KD;++i)
              minn[i]=maxx[i]=p[i];
            maxv=w;
          }
    }T[N];
    void Update(int rt)
    {
        for(int i=0;i<2;++i)
          if(T[rt].ch[i])
            {
              T[rt].maxv=max(T[rt].maxv,T[T[rt].ch[i]].maxv);
              for(int j=0;j<KD;++j)
                {
                  T[rt].minn[j]=min(T[rt].minn[j],T[T[rt].ch[i]].minn[j]);
                  T[rt].maxx[j]=max(T[rt].maxx[j],T[T[rt].ch[i]].maxx[j]);
                }
            }
    }
    bool operator < (const Node &a,const Node &b){return a.p[dn]<b.p[dn];}
    int Buildtree(int l=1,int r=n,int d=0)
    {
        dn=d;
        int m=(l+r>>1);
        nth_element(T+l,T+m,T+r+1);
        T[m].Init();
        if(l!=m) T[m].ch[0]=Buildtree(l,m-1,(d+1)%KD);
        if(m!=r) T[m].ch[1]=Buildtree(m+1,r,(d+1)%KD);
        Update(m);
        return m;
    }
    int ans;
    void Query(int rt=root)
    {
        if(T[rt].p[0] < qp[0] &&
        T[rt].p[1] > qp[1] &&
        qp[0] <= T[rt].p[2]  && T[rt].p[2] <= qp[1])
          ans=max(ans,T[rt].w);
        for(int i=0;i<2;++i)
          if(T[rt].ch[i] &&
          T[T[rt].ch[i]].minn[0] < qp[0] &&
          T[T[rt].ch[i]].maxx[1] > qp[1] &&
          qp[0] <= T[T[rt].ch[i]].maxx[2] && T[T[rt].ch[i]].minn[2] <= qp[1])
            {
              if(T[T[rt].ch[i]].maxx[0] < qp[0] &&
              T[T[rt].ch[i]].minn[1] > qp[1] &&
              qp[0] <= T[T[rt].ch[i]].minn[2] && T[T[rt].ch[i]].maxx[2] <= qp[1])
                ans=max(ans,T[T[rt].ch[i]].maxv);
              else if(T[T[rt].ch[i]].maxv > ans)
                Query(T[rt].ch[i]);
            }
    }
    int nex[N],pre[N],now[N];
    int main()
    {
    //  freopen("bzoj3489.in","r",stdin);
    //  freopen("bzoj3489.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
          scanf("%d",&T[i].w);
        for(int i=1;i<=n;++i)
          {
            pre[i]=now[T[i].w];
            now[T[i].w]=i;
          }
        for(int i=1;i<=n;++i)
          now[i]=n+1;
        for(int i=n;i;--i)
          {
            nex[i]=now[T[i].w];
            now[T[i].w]=i;
          }
        for(int i=1;i<=n;++i)
          {
            T[i].p[0]=pre[i];
            T[i].p[1]=nex[i];
            T[i].p[2]=i;
          }
        Buildtree();
        root=(1+n>>1);
        int x,y;
        for(;m;--m)
          {
            scanf("%d%d",&x,&y);
            qp[0]=min((x+ans)%n+1,(y+ans)%n+1);
            qp[1]=max((x+ans)%n+1,(y+ans)%n+1);
    //        qp[0]=x;
    //        qp[1]=y;
            ans=0;
            Query();
            printf("%d
    ",ans);
          }
        return 0;
    }
  • 相关阅读:
    LeetCode Find Duplicate File in System
    LeetCode 681. Next Closest Time
    LeetCode 678. Valid Parenthesis String
    LeetCode 616. Add Bold Tag in String
    LeetCode 639. Decode Ways II
    LeetCode 536. Construct Binary Tree from String
    LeetCode 539. Minimum Time Difference
    LeetCode 635. Design Log Storage System
    LeetCode Split Concatenated Strings
    LeetCode 696. Count Binary Substrings
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4587108.html
Copyright © 2011-2022 走看看