bzoj 3489: A simple rmq problem
2018-07-15 13:58
316 查看
Description
给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大。如果找不到这样的数,则直接输出0, 强制在线。Solution
设 \(pre[i]\) 表示 \(i\) 之前第一个与 \(a[i]\) 相同的位置\(nxt[i]\) 表示 \(i\) 之后第一个与 \(a[i]\) 相同的位置
满足要求的位置是:
\(l<=i<=r,pre[i]<l,nxt[i]>r\)
可以看成是点 \((i,pre,nxt)\)
用 \(kdtree\) 维护一下包含所有点的区域就行了
#include<bits/stdc++.h> using namespace std; template<class T>void gi(T &x){ int f;char c; for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1; for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f; } const int N=1e5+10; int n,Q,nxt ,pre ,la ,a ,D,rt,ans=0; struct data{ int a[3],mx[3],mn[3],w,l,r,v; inline int& operator [](int x){return a[x];} }t ; inline bool operator <(data p,data q){return p[D]<q[D];} inline void upd(int o){ int l=t[o].l,r=t[o].r; for(int i=0;i<3;i++)t[o].mn[i]=t[o].mx[i]=t[o][i]; for(int i=0;i<3;i++){ if(l)t[o].mn[i]=min(t[o].mn[i],t[l].mn[i]), t[o].mx[i]=max(t[o].mx[i],t[l].mx[i]); if(r)t[o].mn[i]=min(t[o].mn[i],t[r].mn[i]), t[o].mx[i]=max(t[o].mx[i],t[r].mx[i]); } t[o].v=max(t[o].w,max(t[l].v,t[r].v)); } inline int build(int l,int r){ D=rand()%3; int mid=(l+r)>>1,o=mid; nth_element(t+l,t+mid,t+r+1); if(l<mid)t[o].l=build(l,mid-1); if(r>mid)t[o].r=build(mid+1,r); return upd(o),o; } int l,r; inline bool check(int o){ if(t[o].mn[0]>r || t[o].mx[0]<l)return 0; if(t[o].mn[1]>=l)return 0; if(t[o].mx[2]<=r)return 0; return 1; } inline void query(int o){ if(!o || !check(o))return ; if(t[o].v<=ans)return ; if(t[o][0]>=l && t[o][0]<=r && t[o][1]<l && t[o][2]>r)ans=max(ans,t[o].w); query(t[o].l);query(t[o].r); } int main(){ freopen("pp.in","r",stdin); freopen("pp.out","w",stdout); srand(19260817); cin>>n>>Q; for(int i=1;i<=n;i++)gi(a[i]),pre[i]=la[a[i]],la[a[i]]=i; memset(la,0,sizeof(la)); for(int i=n;i>=1;i--)nxt[i]=la[a[i]]?la[a[i]]:n+1,la[a[i]]=i; for(int i=1;i<=n;i++)t[i][0]=i,t[i][1]=pre[i],t[i][2]=nxt[i],t[i].w=a[i]; rt=build(1,n); int x,y; while(Q--){ gi(x);gi(y); l=(x+ans)%n+1;r=(y+ans)%n+1;if(l>r)swap(l,r); ans=0; query(rt); printf("%d\n",ans); } return 0; }
相关文章推荐
- 【31.94%】【BZOJ 3489】A simple rmq problem
- [BZOJ 3489] A simple rmq problem 【可持久化树套树】
- [bzoj3489]A simple rmq problem
- 【BZOJ3489】A simple rmq problem kd-tree
- bzoj 3489: A simple rmq problem 可持久化线段树套可持久化线段树
- bzoj3489 A simple rmq problem(K-D tree三维子空间求最大值)
- BZOJ 3489: A simple rmq problem
- bzoj 3489: A simple rmq problem (KD-tree)
- BZOJ 3489 A simple rmq problem ——KD-Tree
- BZOJ 3489 A simple rmq problem 可持久化树套树
- bzoj3489 A simple rmq problem 可持久化树套树
- bzoj3489: A simple rmq problem (主席树)
- 【BZOJ】【3489】A simple rmq problem
- bzoj3489 A simple rmq problem
- BZOJ 3489 A simple rmq problem
- [BZOJ3489]A simple rmq problem
- bzoj 3489 - A simple rmq problem
- [BZOJ3489]A simple rmq problem(KD-tree||主席树+KD-tree小结)
- bzoj3489 A simple rmq problem
- BZOJ_3489_ A simple rmq problem_KDTree