KD_tree 板子
来源:互联网 发布:sqlserver 大数据导入 编辑:程序博客网 时间:2024/06/12 01:35
例题:3489: A simple rmq problem
在[l,r]内找只出现一次的,最大的数
用pre记录每个位置的数上次出现位置,nex记录下次出现位置
一个位置i的值在[l,r]内只出现一次,那么 l <= i <= r , prei< l, nexi>r,所以给一个点三维坐标(i,prei,nexi),询问时用kd-tree找(l~r,0~l-1,r+1~n+1)里最大的值
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;int read(){ char c; int x; while(!((c=getchar())>='0'&&c<='9')); x=c-'0'; while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0'; return x;}void up(int &x,const int y){if(x<y)x=y;}void down(int &x,const int y){if(x>y)x=y;}const int maxn = 110000;const int maxd = 3;struct Kd_tree{ int s,c,pos[maxd],u[maxd],d[maxd],lc,rc;}kd[maxn]; int root;int n,m;int cmp_d;bool cmp(const Kd_tree &x,const Kd_tree &y) { return x.pos[cmp_d]<y.pos[cmp_d]; }void push_up(const int &x){ const int lc=kd[x].lc,rc=kd[x].rc; if(lc) { for(int i=0;i<maxd;i++) up(kd[x].u[i],kd[lc].u[i]), down(kd[x].d[i],kd[lc].d[i]); up(kd[x].c,kd[lc].c); } if(rc) { for(int i=0;i<maxd;i++) up(kd[x].u[i],kd[rc].u[i]), down(kd[x].d[i],kd[rc].d[i]); up(kd[x].c,kd[rc].c); }}int Build(int l,int r,int D){ cmp_d=D; int mid=(l+r)>>1; std::nth_element(kd+l,kd+mid,kd+r+1,cmp); for(int i=0;i<maxd;i++) kd[mid].u[i]=kd[mid].d[i]=kd[mid].pos[i]; kd[mid].c=kd[mid].s; kd[mid].lc=kd[mid].rc=0; if(l==r) return mid; if(l!=mid) kd[mid].lc=Build(l,mid-1,(D+1)%3); if(mid!=r) kd[mid].rc=Build(mid+1,r,(D+1)%3); push_up(mid); return mid;}int Pu[maxd],Pd[maxn];int Cal(const int x){ if(!x) return 0; for(int i=0;i<maxd;i++) if(kd[x].d[i]>Pu[i]||kd[x].u[i]<Pd[i]) return 0; return kd[x].c;}int Ask(const int x){ for(int i=0;i<maxd;i++) if(kd[x].d[i]>Pu[i]||kd[x].u[i]<Pd[i]) return 0; bool flag=true; for(int i=0;i<maxd;i++) if(!(Pd[i]<=kd[x].d[i]&&kd[x].u[i]<=Pu[i])) {flag=false; break;} if(flag) return kd[x].c; int re=0; flag=true; for(int i=0;i<maxd;i++) if(!(Pd[i]<=kd[x].pos[i]&&kd[x].pos[i]<=Pu[i])) {flag=false; break;} if(flag) re=kd[x].s; int k1=Cal(kd[x].lc),k2=Cal(kd[x].rc); if(k1>k2) { if(k1>re) up(re,Ask(kd[x].lc)); if(k2>re) up(re,Ask(kd[x].rc)); } else { if(k2>re) up(re,Ask(kd[x].rc)); if(k1>re) up(re,Ask(kd[x].lc)); } return re;}int Posi[maxn];int a[maxn],pre[maxn],nex[maxn];int main(){ n=read(),m=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=n;i++) pre[i]=Posi[a[i]],Posi[a[i]]=i; for(int i=1;i<=n;i++) Posi[i]=n+1; for(int i=n;i>=1;i--) nex[i]=Posi[a[i]],Posi[a[i]]=i; for(int i=1;i<=n;i++) kd[i].s=a[i],kd[i].pos[0]=i,kd[i].pos[1]=pre[i],kd[i].pos[2]=nex[i]; Build(1,n,0); root=(1+n)>>1; int ans=0; while(m--) { int x=(read()+ans)%n+1,y=(read()+ans)%n+1; int l=min(x,y),r=max(x,y); Pd[0]=l,Pu[0]=r; Pd[1]=0,Pu[1]=l-1; Pd[2]=r+1,Pu[2]=n+1; printf("%d\n",ans=Ask(root)); } return 0;}
1 0
- KD_tree 板子
- 板子
- 板子
- KD_tree算法的使用
- BZOJ 2648/2716(SJY摆棋子-KD_Tree)[Template:KD_Tree]
- bzoj4066(kd_tree 维护权值)
- kd_tree搜索最近邻点
- [模版] 带部分重构的KD_Tree
- bzoj1941 Hide and Seek(kd_Tree模板题)
- bzoj2468 SJY摆棋子(kd_Tree模板题)
- 测试板子
- 板子总结
- 入手板子
- 新板子
- Ivus 板子
- dinic 板子
- manacher板子
- 左偏树 板子
- javascript运行机制详解
- ACM程序设计 书中题目Z
- Android CMake
- ccf 目录格式转换
- 函数式编程
- KD_tree 板子
- Maven 手动添加JAR包到本地maven仓库,但在项目中依旧报错找不到JAR包解决方法
- VR小项目(三)
- [leetcode] 134. Gas Station
- CSS优先级算法
- SpringBoot Schedule 配置
- Maven手动添加依赖的jar文件到本地Maven仓库
- 深入PHP面向对象、模式与实践——高级特性(4)
- Spring整合Hibernate的方法