[bzoj3489] A simple rmq problem 解题报告
来源:互联网 发布:封闭源代码软件 编辑:程序博客网 时间:2024/05/07 12:41
说几种比较傻逼的做法:
考虑一个点i,设它前面第一个和它相等的点的位置是
就这样跑了17s。。
我们反过来考虑,考虑一次询问对点的要求,是
就这样跑了10s。。
代码(可持久化k-d树):
#include<cstdio>#include<iostream>using namespace std;#include<algorithm>#include<cstring>#include<cmath>const int N=1e5+5,M=2e5+5;int a[N];int pos[N];void in(int &x){ char c=getchar(); while(c<'0'||c>'9')c=getchar(); for(x=0;c>='0'&&c<='9';c=getchar())x=x*10+(c^'0');}const int Log=18;struct KS{ int ls,rs; int lx,rx,ly,ry; int max;}kdt[N*(Log+2)];int root[N];int ktot=1;struct PS{ int x,y;}point[N];bool cmpx(const PS & a,const PS & b){ return a.x<b.x;}bool cmpy(const PS & a,const PS & b){ return a.y<b.y;}bool inrange(int lx,int rx,int ly,int ry,int Lx,int Rx,int Ly,int Ry){ return Lx<=lx&&rx<=Rx&&Ly<=ly&&ry<=Ry;}void out(int node){ printf("%d{[%d,%d]-[%d,%d] max=%d}\n",node,kdt[node].lx,kdt[node].rx,kdt[node].ly,kdt[node].ry,kdt[node].max);}void build(int &node,int pl,int pr,bool depth){ node=ktot++; kdt[node].lx=kdt[node].rx=point[pl].x; kdt[node].ly=kdt[node].ry=point[pl].y; for(int i=pl+1;i<=pr;++i){ kdt[node].lx=min(kdt[node].lx,point[i].x); kdt[node].rx=max(kdt[node].rx,point[i].x); kdt[node].ly=min(kdt[node].ly,point[i].y); kdt[node].ry=max(kdt[node].ry,point[i].y); } //printf("[%d,%d]=",pl,pr); //out(node); if(pl!=pr){ int pm=pl+pr>>1; if(depth)nth_element(point+pl,point+pm,point+pr+1,cmpx); else nth_element(point+pl,point+pm,point+pr+1,cmpy); //for(int i=pl;i<=pr;++i)printf("(%d,%d) ",point[i].x,point[i].y); //puts(""); build(kdt[node].ls,pl,pm,depth^1); build(kdt[node].rs,pm+1,pr,depth^1); }}void add(int &node,int pl,int pr,int x,int A){ //printf("Add (%d) at ",A); kdt[ktot]=kdt[node]; //out(node); node=ktot++; kdt[node].max=max(kdt[node].max,A); //out(node); if(pl!=pr){ //out(kdt[node].ls),out(kdt[node].rs); if(x<=pl+pr>>1)add(kdt[node].ls,pl,pl+pr>>1,x,A); else add(kdt[node].rs,(pl+pr>>1)+1,pr,x,A); }}int lastans;void query(int node,int Lx,int Rx,int Ly,int Ry){ if(kdt[node].rx<Lx||kdt[node].lx>Rx||kdt[node].ly>Ry||kdt[node].ry<Ly)return; if(inrange(kdt[node].lx,kdt[node].rx,kdt[node].ly,kdt[node].ry,Lx,Rx,Ly,Ry)){ //printf("Get:"); //out(node); lastans=max(lastans,kdt[node].max); } if(kdt[node].max<=lastans)return; query(kdt[node].ls,Lx,Rx,Ly,Ry),query(kdt[node].rs,Lx,Rx,Ly,Ry);}struct PointS{ int last,i,next; bool operator < (const PointS & o)const{ return last<o.last; }}pnt[N];int main(){ freopen("bzoj_3489.in","r",stdin); int n,m; in(n),in(m); for(int i=1;i<=n;++i)in(a[i]); for(int i=1;i<=n;++i){ pnt[i].last=pos[a[i]]+1; pos[a[i]]=i; } for(int i=n;i;--i)pos[a[i]]=n+1; for(int i=n;i;--i){ pnt[i].next=pos[a[i]]-1; pos[a[i]]=i; } for(int i=n;i;--i)pnt[i].i=i; for(int i=n;i;--i)point[i]=(PS){i,pnt[i].next}; sort(pnt+1,pnt+n+1); build(root[0],1,n,0); for(int i=n;i;--i)pos[point[i].x]=i; for(int i=1,j=1;i<=n;++i){ //printf("---%d---\n",i); root[i]=root[i-1]; for(;pnt[j].last==i;++j){ //printf("%d ",pnt[j].i); add(root[i],1,n,pos[pnt[j].i],a[pnt[j].i]); } //puts(""); } //cout<<ktot<<endl; int l,r; while(m--){ in(l),in(r); l=(l+lastans)%n+1,r=(r+lastans)%n+1; if(l>r)swap(l,r); lastans=0; query(root[l],l,r,r,n); printf("%d\n",lastans); }}
总结:
①我们可以把每个数看成点,也可以把询问看成点,这两种方式效果是不一样的,要都想一想。
0 0
- [bzoj3489] A simple rmq problem 解题报告
- 【BZOJ3489】A simple rmq problem
- BZOJ3489 A simple rmq problem
- bzoj3489: A simple rmq problem
- BZOJ3489: A simple rmq problem kdtree
- [BZOJ3489]A simple rmq problem(kd-tree)
- A simple problem解题报告
- [BZOJ3489]A simple rmq problem(可持久化树套树||K-D tree)
- [BZOJ3489]A simple rmq problem(KD-tree||主席树+KD-tree小结)
- 3489: A simple rmq problem
- HYSBZ3489-A simple rmq problem
- poj3468- A Simple Problem with Integers-解题报告-线段树
- BZOJ 3489 A simple rmq problem
- 【31.94%】【BZOJ 3489】A simple rmq problem
- bzoj 3489: A simple rmq problem
- BZOJ 3489 A simple rmq problem
- BZOJ 3489: A simple rmq problem 树套树
- POJ 3468 A Simple Problem with Integers (线段树成段更新) 解题报告
- bzoj 1911: [Apio2010]特别行动队(斜率优化)
- Sense of reading-Emotion hurt man
- 数据挖掘算法逻辑回归-R实现
- 许智宏:对转基因作物研发未来的忧虑
- bzoj 4318: OSU!|概率与期望|dp
- [bzoj3489] A simple rmq problem 解题报告
- java jdk7 并行计算框架 fork/join
- 数据挖掘算法-ID3决策树
- 因为我们是OIer
- Servlet - 基础
- c++中深拷贝与浅拷贝
- AppWidget的开发
- [bzoj3744]Gty的妹子序列 解题报告
- 数据挖掘算法-BP神经网络