BZOJ 3585: mex( 离线 + 线段树 )
生活随笔
收集整理的這篇文章主要介紹了
BZOJ 3585: mex( 离线 + 线段树 )
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
離線, 詢問排序.
先處理出1~i的答案, 這樣可以回答左端點為1的詢問.完成后就用seq(1)將1到它下一次出現(xiàn)的位置前更新. 不斷這樣轉(zhuǎn)移就OK了
--------------------------------------------------------------------
#include<bits/stdc++.h>using namespace std;#define M(l, r) (((l) + (r)) >> 1)const int maxn = 200009;int id[maxn], N = 0, seq[maxn], n, T[maxn];bool F[maxn];struct link {int pos;link* next;} A[maxn], *head[maxn], *pit = A;struct Q {int l, r, p;inline void read(int _p) {scanf("%d%d", &l, &r); l--; r--;p = _p;}bool operator < (const Q &q) const {return l < q.l;}} B[maxn];struct Node {Node *l, *r;int tag;Node() {tag = -1;l = r = NULL;}inline void pushdown() {if(~tag) {l->tag = ~l->tag ? min(l->tag, tag) : tag;r->tag = ~r->tag ? min(r->tag, tag) : tag;tag = -1;}}} pool[maxn << 1], *pt = pool, *root;void build(Node* t, int l, int r) {if(r > l) {int m = M(l, r);build(t->l = pt++, l, m);build(t->r = pt++, m + 1, r);} else ? ?t->tag = T[l - 1];}int L, R, v;void modify(Node* t, int l, int r) {if(L <= l && r <= R) ? ?t->tag = ~t->tag ? min(t->tag, v) : v;else {t->pushdown();int m = M(l, r);if(L <= m) modify(t->l, l, m);if(m < R) modify(t->r, m + 1, r);}}int query(Node* t, int l, int r) {if(l == r) ? ?return t->tag;t->pushdown();int m = M(l, r);return L <= m ? query(t->l, l, m) : query(t->r, m + 1, r);}int ans[maxn];int main() {freopen("test.in", "r", stdin);freopen("test.out", "w", stdout);memset(head, 0, sizeof head);memset(F, false, sizeof F);int m;cin >> n >> m;for(int i = 0; i < n; i++) {scanf("%d", seq + i);id[i] = seq[i];}sort(id, id + n);N = unique(id, id + n) - id;for(int i = 0; i < n; i++) ? ?seq[i] = lower_bound(id, id + N, seq[i]) - id;for(int i = n - 1; ~i; i--) {int t = seq[i];pit->pos = i;pit->next = head[t];head[t] = pit++;}for(int i = 0; i < n; i++) {if(id[seq[i]] < maxn) F[id[seq[i]]] = true;T[i] = i ? T[i - 1] : 0;while(F[T[i]]) T[i]++;}build(root = pt++, 1, n);for(int i = 0; i < m; i++) ? ?B[i].read(i);sort(B, B + m);int p = 0;for(int i = 0; i < n; i++) {while(p < m && B[p].l == i) {L = B[p].r + 1;ans[B[p].p] = query(root, 1, n);p++;}if(i == n - 1 || p >= m) break;head[seq[i]] = head[seq[i]]->next;L = i + 1; R = head[seq[i]] ? head[seq[i]]->pos : n; v = id[seq[i]];modify(root, 1, n);}for(int i = 0; i < m; i++) ? ?printf("%d\n", ans[i]);return 0;}--------------------------------------------------------------------?
3585: mex
Time Limit:?20 Sec??Memory Limit:?128 MBSubmit:?454??Solved:?232
[Submit][Status][Discuss]
Description
有一個長度為n的數(shù)組{a1,a2,...,an}。m次詢問,每次詢問一個區(qū)間內(nèi)最小沒有出現(xiàn)過的自然數(shù)。
Input
第一行n,m。
第二行為n個數(shù)。
從第三行開始,每行一個詢問l,r。
Output
一行一個數(shù),表示每個詢問的答案。
Sample Input
5 52 1 0 2 1
3 3
2 3
2 4
1 2
3 5
Sample Output
12
3
0
3
HINT
數(shù)據(jù)規(guī)模和約定
對于100%的數(shù)據(jù):
1<=n,m<=200000
0<=ai<=109
1<=l<=r<=n
對于30%的數(shù)據(jù):
1<=n,m<=1000
Source
By 佚名提供
?
轉(zhuǎn)載于:https://www.cnblogs.com/JSZX11556/p/4708066.html
總結(jié)
以上是生活随笔為你收集整理的BZOJ 3585: mex( 离线 + 线段树 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 学习笔记01
- 下一篇: [SDOI2015]权值