BZOJ3339 Rmq Problem
【bzoj3339】Rmq Problem
Description
Input
Output
Sample Input
7 5 0 2 1 0 1 3 2 1 3 2 3 1 4 3 6 2 7
Sample Output
3 0 3 2 4
HINT
orz hzwer学长
转-----------------------------------
这一题在线似乎比较麻烦,至于离线。
首先按照左端点将询问排序
然后一般可以这样考虑
首先如何得到1-i的sg值呢
这个可以一开始扫一遍完成
接着考虑l-r和l+1-r的答案有何不同
显然是l-next[l]-1这一段所有sg值大于a[l]的变为a[l]
这一步如果暴力修改的话只有30分
但是修改区间我们可以想到线段树,这样就能a了
#include<cstdio> #include<cctype> #include<cstring> #include<algorithm> using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } const int maxn=200010; const int inf=1e9; int n,m,A[maxn],mark[maxn],val[maxn],next[maxn],last[maxn],ans[maxn],minv[maxn*3]; struct Query { int id,l,r; bool operator < (const Query& ths) const {return l<ths.l;} }q[maxn]; void build(int o,int l,int r) { if(l==r) minv[o]=val[l]; else { int mid=l+r>>1,lc=o<<1,rc=lc|1; build(lc,l,mid);build(rc,mid+1,r); minv[o]=inf; } } void pushdown(int o) { int lc=o<<1,rc=lc|1; minv[lc]=min(minv[o],minv[lc]); minv[rc]=min(minv[o],minv[rc]); } int query(int o,int l,int r,int pos) { if(l!=r&&minv[o]!=inf) pushdown(o); if(l==r) return minv[o]; int mid=l+r>>1,lc=o<<1,rc=lc|1; if(pos<=mid) return query(lc,l,mid,pos); return query(rc,mid+1,r,pos); } void update(int o,int l,int r,int ql,int qr,int v) { if(l!=r&&minv[o]!=inf) pushdown(o); if(ql<=l&&r<=qr) minv[o]=min(minv[o],v); else { int mid=l+r>>1,lc=o<<1,rc=lc|1; if(ql<=mid) update(lc,l,mid,ql,qr,v); if(qr>mid) update(rc,mid+1,r,ql,qr,v); } } int main() { n=read();m=read(); for(int i=1;i<=n;i++) A[i]=read(); for(int i=1;i<=n;i++) { mark[A[i]]=1; for(int j=val[i-1];;j++) if(!mark[j]) {val[i]=j;break;} } for(int i=n;i;i--) next[i]=last[A[i]]?last[A[i]]:n+1,last[A[i]]=i; build(1,1,n); for(int i=1;i<=m;i++) q[q[i].id=i].l=read(),q[i].r=read(); sort(q+1,q+m+1); int cur=1; for(int i=1;i<=m;i++) { while(cur<q[i].l) { update(1,1,n,cur,next[cur]-1,A[cur]); cur++; } ans[q[i].id]=query(1,1,n,q[i].r); } for(int i=1;i<=m;i++) printf("%d\n",ans[i]); return 0; }