【BZOJ】【3339】Rmq Problem

离线+线段树


  Orz Hzwer,引用题解:

这一题在线似乎比较麻烦

至于离线。。

首先按照左端点将询问排序

然后一般可以这样考虑

首先如何得到1-i的sg值呢

这个可以一开始扫一遍完成

接着考虑l-r和l+1-r的答案有何不同

显然是l-next[l]-1这一段所有sg值大于a[l]的变为a[l]

这一步如果暴力修改的话只有30分

但是修改区间我们可以想到线段树,这样就能a了

  晚上写题有点晕……忘了把当前时刻now置为q[i].l了,这种傻逼错误居然也犯……

  1 /**************************************************************
  2     Problem: 3339
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:1444 ms
  7     Memory:11432 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 3339
 11 #include<vector>
 12 #include<cstdio>
 13 #include<cstring>
 14 #include<cstdlib>
 15 #include<iostream>
 16 #include<algorithm>
 17 #define rep(i,n) for(int i=0;i<n;++i)
 18 #define F(i,j,n) for(int i=j;i<=n;++i)
 19 #define D(i,j,n) for(int i=j;i>=n;--i)
 20 using namespace std;
 21 typedef long long LL;
 22 inline int getint(){
 23     int r=1,v=0; char ch=getchar();
 24     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
 25     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
 26     return r*v;
 27 }
 28 const int N=2e5+10,INF=1e9;
 29 /*******************template********************/
 30  
 31 int n,m,a[N],mark[N],sg[N],ans[N],last[N],nxt[N];
 32 struct ques{
 33     int l,r,num;
 34 }q[N];
 35 bool operator < (ques a,ques b){return a.l<b.l || (a.l==b.l && a.r<b.r);}
 36  
 37 int t[N<<2];
 38 #define L (o<<1)
 39 #define R (o<<1|1)
 40 #define mid (l+r>>1)
 41 #define lch L,l,mid
 42 #define rch R,mid+1,r
 43 void Push_down(int o){
 44     if (t[o]!=INF){
 45         t[L]=min(t[L],t[o]); t[R]=min(t[R],t[o]);
 46         t[o]=INF;
 47     }
 48 }
 49 void build(int o,int l,int r){
 50     if (l==r) t[o]=sg[l];
 51     else{
 52         t[o]=INF;
 53         build(lch); build(rch);
 54     }
 55 }
 56 void update(int o,int l,int r,int ql,int qr,int v){
 57     if (ql<=l && qr>=r) t[o]=min(t[o],v);
 58     else{
 59         Push_down(o);
 60         if (ql<=mid) update(lch,ql,qr,v);
 61         if (qr>mid) update(rch,ql,qr,v);
 62     }
 63 }
 64 int query(int o,int l,int r,int pos){
 65     if (l==r) return t[o];
 66     else{
 67         Push_down(o);
 68         if (pos<=mid) return query(lch,pos);
 69         else return query(rch,pos);
 70     }
 71 }
 72 int main(){
 73 #ifndef ONLINE_JUDGE
 74     freopen("3339.in","r",stdin);
 75     freopen("3339.out","w",stdout);
 76 #endif 
 77     n=getint(); m=getint();
 78     F(i,1,n) a[i]=getint();
 79     int k=0;
 80     F(i,1,n){
 81         mark[a[i]]=1;
 82         if (a[i]==k) while(mark[k]) k++;
 83         sg[i]=k;
 84     }
 85     build(1,1,n);
 86     D(i,n,1){
 87         nxt[i]=last[a[i]];
 88         last[a[i]]=i;
 89     }
 90     F(i,1,m){
 91         q[i].l=getint(); q[i].r=getint(); q[i].num=i;
 92     }
 93     sort(q+1,q+m+1);
 94     int now=1;
 95     F(i,1,m){
 96         F(j,now,q[i].l-1){
 97             if (!nxt[j]) nxt[j]=n+1;
 98             update(1,1,n,j,nxt[j]-1,a[j]);
 99         }
100         now=q[i].l;
101         ans[q[i].num]=query(1,1,n,q[i].r);
102     }
103     F(i,1,m) printf("%d\n",ans[i]);
104     return 0;
105 }
View Code

3339: Rmq Problem

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 683  Solved: 328
[Submit][Status][Discuss]

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

Source

[Submit][Status][Discuss]
posted @ 2015-06-23 23:02  Tunix  阅读(...)  评论(...编辑  收藏