【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
0 2 1 0 1 3 2
1 3
2 3
1 4
3 6
2 7
Sample Output
3
0
3
2
4
0
3
2
4
HINT
分析
离线算法。
对于[l,r]区间的询问,我们可以线性求出来,然后考虑[l,r]与[l+1,r]区间有什么不同,在a[l]下一次出现的位置之前,所有大于a[l]的mex,都变成是a[l],因为 [l+1,a[l]下一次出现的位置-1],这个区间内没有a[l]了,大于它的数当然可以是它。
所以将询问的先按左端点排序,然后递增左端点,不断更新,用线段树维护。
code
1 #include<cstdio> 2 #include<algorithm> 3 #define lson l,m,rt<<1 4 #define rson m+1,r,rt<<1|1 5 6 using namespace std; 7 8 const int MAXN = 200100; 9 const int INF = 1e9; 10 11 struct Que{ 12 int l,r,id; 13 bool operator < (const Que &x) const 14 { 15 return l < x.l; 16 } 17 }q[MAXN]; 18 int a[MAXN],sg[MAXN],mn[MAXN<<2]; 19 int next[MAXN],last[MAXN],ans[MAXN]; 20 bool vis[MAXN]; 21 int n,m,k = 0,now; 22 23 int read() 24 { 25 int x=0;char ch=getchar(); 26 while(ch<'0'||ch>'9') {ch=getchar(); } 27 while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar(); } 28 return x; 29 } 30 void pushdown(int rt) 31 { 32 if (mn[rt]!=INF) 33 { 34 mn[rt<<1] = min(mn[rt],mn[rt<<1]); 35 mn[rt<<1|1] = min(mn[rt],mn[rt<<1|1]); 36 } 37 } 38 void build(int l,int r,int rt) 39 { 40 mn[rt] = INF; 41 if (l==r) 42 { 43 mn[rt] = sg[l]; 44 return ; 45 } 46 int m = (l+r)>>1; 47 build(lson); 48 build(rson); 49 } 50 void update(int l,int r,int rt,int L,int R,int v) 51 { 52 if (L<=l&&r<=R) 53 { 54 mn[rt] = min(mn[rt],v); 55 return ; 56 } 57 pushdown(rt); 58 int m = (l+r)>>1; 59 if (L<=m) update(lson,L,R,v); 60 if (R>m) update(rson,L,R,v); 61 } 62 int query(int l,int r,int rt,int p) 63 { 64 if (l==r) return mn[rt]; 65 pushdown(rt); 66 int m = (l+r)>>1; 67 if (p<=m) return query(lson,p); 68 else return query(rson,p); 69 } 70 71 int main() 72 { 73 n = read();m = read(); 74 for (int i=1; i<=n; ++i) 75 a[i] = read(); 76 for (int i=1;i<=m; ++i) 77 q[i].l = read(), q[i].r = read(), q[i].id = i; 78 sort(q+1,q+m+1); 79 for (int i=1; i<=n; ++i) 80 { 81 vis[a[i]] = true; 82 while (vis[k]) k++; 83 sg[i] = k; 84 } 85 build(1,n,1); 86 for (int i=n; i; --i) 87 next[i] = last[a[i]], last[a[i]] = i; 88 now = 1; 89 90 for (int i=1; i<=m; ++i) 91 { 92 while (now<q[i].l) 93 { 94 if (!next[now]) next[now] = n+1; 95 update(1,n,1,now,next[now]-1,a[now]); 96 now++; 97 } 98 ans[q[i].id] = query(1,n,1,q[i].r); 99 } 100 for (int i=1; i<=m; ++i) 101 printf("%d ",ans[i]); 102 return 0; 103 }
(……)