1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int inf=1e9; int n,m,w[2000000],lg2[1500000]; int pos[1500000],lst[1500000],dep[1500000],id,mm,S,ch[1500000][2],stack[1500000]; struct LIM_RMQ { int w[1500000],bl[1500000],blo,L[150000],R[150000],pos[10000],val[150000],minn[150000],minpos[150000],t[1000],n_st; struct ST_node{int f,id;bool operator <(const ST_node &tmp)const{return f<tmp.f;}}; struct STable { ST_node a[4][12]; void make(int w[],int n) { for(int i=1;i<=n;i++)a[0][i]=(ST_node){w[i],i}; for(int i=1;(1<<i)<=n;i++) for(int j=1;j+(1<<i)-1<=n;j++) a[i][j]=min(a[i-1][j],a[i-1][j+(1<<(i-1))]); } ST_node query(int l,int r) { int len=lg2[r-l+1]; return min(a[len][l],a[len][r-(1<<len)+1]); } }st[10000]; struct STable_block { ST_node a[20][150000]; void make(int w[],int n) { for(int i=1;i<=n;i++)a[0][i]=(ST_node){w[i],i}; for(int i=1;(1<<i)<=n;i++) for(int j=1;j+(1<<i)-1<=n;j++) a[i][j]=min(a[i-1][j],a[i-1][j+(1<<(i-1))]); } ST_node query(int l,int r) { int len=lg2[r-l+1]; return min(a[len][l],a[len][r-(1<<len)+1]); } }st_block; void make(int a[],int n) { for(int i=1;i<=n;i++)w[i]=a[i]; lg2[1]=0;for(int i=2;i<=n;i++)lg2[i]=lg2[i>>1]+1; blo=max(lg2[n]>>1,1); for(int i=1;i<=n;i++)bl[i]=(i-1)/blo+1; for(int i=1;i<=bl[n];i++)L[i]=(i-1)*blo+1,R[i]=min(i*blo,n),minn[i]=inf; w[0]=w[1]-1; for(int i=1;i<=bl[n];i++) { int tmp=0,nn=0; for(int j=L[i];j<=R[i];j++) { t[++nn]=w[j],tmp=tmp<<1|(w[j]-w[j-1]==1?1:0); if(w[j]<minn[i])minn[i]=w[j],minpos[i]=j; } if(!pos[tmp])st[pos[tmp]=++n_st].make(t,nn); val[i]=pos[tmp]; } st_block.make(minn,bl[n]); } ST_node query_block(int id,int l,int r){ST_node t=st[val[id]].query(l-L[id]+1,r-L[id]+1);return (ST_node){t.f,t.id+L[id]-1};} int query(int l,int r) { int bll=bl[l],blr=bl[r]; if(bll==blr)return query_block(bll,l,r).id; int ml=query_block(bll,l,R[bll]).id,mr=query_block(blr,L[blr],r).id,mm; if(w[ml]<w[mr])mm=ml;else mm=mr; if(bll+1<=blr-1) { int mmid=minpos[st_block.query(bll+1,blr-1).id]; if(w[mmid]<w[mm])mm=mmid; } return mm; } }a; void dfs(int u,int depth) { lst[u]=++id,pos[id]=u;dep[id]=depth; for(int i=0;i<=1;i++) if(ch[u][i]) { dfs(ch[u][i],depth+1); pos[++id]=u,dep[id]=depth; } } int getin() { int x=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-48,ch=getchar(); return x; } int wt[30]; void putout(int x) { if(!x){putchar('0');return;} int l=0; while(x)wt[++l]=x%10,x/=10; while(l)putchar(wt[l--]+48); puts(""); } void build_tree() { int top=1;stack[1]=S=1; for(int i=2;i<=n;i++) { int lst=0; while(top&&w[i]>w[stack[top]])lst=stack[top--]; if(lst)ch[i][0]=lst; if(top)ch[stack[top]][1]=i;else S=i; stack[++top]=i; } dfs(S,1); } int main() { n=getin(),m=getin(); for(int i=1;i<=n;i++)w[i]=getin(); build_tree(); a.make(dep,id); for(int i=1;i<=m;i++) { int l=lst[getin()],r=lst[getin()]; if(l>r)swap(l,r); putout(w[pos[a.query(l,r)]]); } }
|