[BZOJ3489]A simple rmq problem

题解:

并没有想到。。

我们用前驱后继来表示出题目要求

即pre[i]<l且scc[i]>r且l<=i<=r

即4维偏序

使用树套树可以用主席树套线段树(很毒瘤??)

那么会kd-tree就比较简单了,3维空间查找

代码写完编译运行一遍过就很爽了

代码:

 

#include <bits/stdc++.h>
using namespace std;
#define IL inline
#define rint register int 
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define mid ((h+t)/2)
const int INF=1e9;
const int N=3e5;
int n,m;
char ss[1<<24],*A=ss,*B=ss;
IL char gc()
{
  return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
}
template<class T>void read(T &x)
{
  rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
  while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
}
IL void umax(int &x,int y)
{
  if (x<y) x=y;
}
IL void umin(int &x,int y)
{
  if (x>y) x=y;
}
struct re
{
  int d[3],num;
}p[N];
int cmp_d,ans,a[N];
bool cmp(re x,re y)
{
  return(x.d[cmp_d]<y.d[cmp_d]);
}
struct kd
{
  int ls[N],rs[N],Mx[N],My[N],Mz[N],Nx[N],Ny[N],Nz[N],maxn[N];
  void updata(int x)
  {
    if (ls[x])
    {
      umax(Mx[x],Mx[ls[x]]);
      umax(My[x],My[ls[x]]);
      umax(Mz[x],Mz[ls[x]]);
      umin(Nx[x],Nx[ls[x]]);
      umin(Ny[x],Ny[ls[x]]);
      umin(Nz[x],Nz[ls[x]]);
      umax(maxn[x],maxn[ls[x]]);
    }
    if (rs[x])
    {
      umax(Mx[x],Mx[rs[x]]);
      umax(My[x],My[rs[x]]);
      umax(Mz[x],Mz[rs[x]]);
      umin(Nx[x],Nx[rs[x]]);
      umin(Ny[x],Ny[rs[x]]);
      umin(Nz[x],Nz[rs[x]]);
      umax(maxn[x],maxn[rs[x]]);
    }
  }
  int build(int h,int t,int o)
  {
    cmp_d=o; nth_element(p+h,p+mid,p+t+1,cmp);
    int x=mid;
    Mx[x]=Nx[x]=p[x].d[0];
    My[x]=Ny[x]=p[x].d[1];
    Mz[x]=Nz[x]=p[x].d[2];
    maxn[x]=p[x].num;
    if (h!=x) ls[x]=build(h,mid-1,(o+1)%3); else ls[x]=0;
    if (t!=x) rs[x]=build(mid+1,t,(o+1)%3); else rs[x]=0;
    updata(x);
    return x;
  }
  void query(int k,int x1,int x2,int y,int z)
  {
    if (!k||maxn[k]<ans||Mx[k]<x1||Nx[k]>x2||Ny[k]>=y||Mz[k]<=z) return;
    if (p[k].d[0]>=x1&&p[k].d[0]<=x2&&p[k].d[1]<y&&p[k].d[2]>z&&p[k].num>ans)
      ans=p[k].num;
    query(ls[k],x1,x2,y,z); query(rs[k],x1,x2,y,z);
  }
}kd;
map<int,int> M;
int pre[N],scc[N];
int main()
{
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
  read(n); read(m);
  rep(i,1,n)
  { 
    read(a[i]);
    int kk=M[a[i]];
    if (kk)
    {
      scc[kk]=i; pre[i]=kk;
    }
    M[a[i]]=i;
  }
  rep(i,1,n) if (!scc[i]) scc[i]=n+1;
  rep(i,1,n) p[i].num=a[i],p[i].d[0]=i,p[i].d[1]=pre[i],p[i].d[2]=scc[i];
  int rt=kd.build(1,n,0);
  rep(i,1,m)
  {
    int x,y;
    read(x); read(y);
    x=(ans+x)%n+1,y=(ans+y)%n+1;
    if (x>y) swap(x,y);
    ans=0;
    kd.query(rt,x,y,x,y);
    printf("%d\n",ans); 
  }
  return 0;
}

 

posted @ 2018-07-10 23:07  尹吴潇  阅读(165)  评论(0编辑  收藏  举报