zoukankan      html  css  js  c++  java
  • BZOJ 3585 mex

    题目已经没有了

    思路:

    莫队+分块

    首先有一个结论:所有的答案都在0到n之间,用反正法就能证明,所以所有大于n的数都可以看成n

    离线,对询问区间进行莫队,再对答案的范围0到n进行分块

    复杂度(n+2*m)√n

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define pi acos(-1.0)
    #define LL long long
    //#define mp make_pair
    #define pb push_back
    #define ls rt<<1, l, m
    #define rs rt<<1|1, m+1, r
    #define ULL unsigned LL
    #define pll pair<LL, LL>
    #define pii pair<int, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
    //head
    
    const int N = 2e5 + 5;
    int a[N], cnt[N], bl[N], ans[N], l[555], r[555], block[555], blo, n;
    struct node {
        int l, r, bl, id;
        bool operator < (const node & t) const {
            if(bl == t.bl) return r < t.r;
            else bl < t.bl;
        }
    }Q[N];
    void add(int x) {
        if(!cnt[x]) block[bl[x]]++;
        cnt[x] ++;
    }
    void del(int x) {
        cnt[x]--;
        if(!cnt[x]) block[bl[x]]--;
    }
    int query() {
        int i;
        for (i = bl[0]; i <= bl[n]; i++) if(block[i] != r[i] - l[i] + 1) break;
        for (int j = l[i]; j <= r[i]; j++) if(!cnt[j]) return j;
    }
    int main() {
        int m;
        while(~scanf("%d%d", &n, &m)) {
            for (int i = 1; i <= n; i++) {
                scanf("%d", &a[i]);
                if(a[i] >= n) a[i] = n;
            }
            blo = sqrt(n+1);
            for (int i = 0; i <= n; i++) bl[i] = i/blo + 1;
            for (int i = bl[0]; i <= bl[n]; i++) {
                l[i] = (i-1)*blo;
                r[i] = min(i*blo-1, n);
            }
            blo = sqrt(n);
            for (int i = 1; i <= m; i++) {
                scanf("%d%d", &Q[i].l, &Q[i].r);
                Q[i].bl = (Q[i].l - 1)/blo + 1;
                Q[i].id = i;
            }
            sort(Q+1, Q+1+m);
            mem(cnt, 0);
            mem(block, 0);
            int l = 1, r = 0;
            for (int i = 1; i <= m; i++) {
                while(r < Q[i].r) r++, add(a[r]);
                while(r > Q[i].r) del(a[r]), r--;
                while(l < Q[i].l) del(a[l]), l++;
                while(l > Q[i].l) l--, add(a[l]);
                ans[Q[i].id] = query();
            }
            for (int i = 1; i <= m; i++) printf("%d
    ", ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    hdu 5916
    hdu 5918
    hdu 5914 Triangle
    hdu 5912Fraction
    遗传算法初学习
    hdu 5873 Football Games
    JAVA 定时器的三种方法
    java反射对实体类取值和赋值,可以写成通过实体类获取其他元素的数据,很方便哦~~~
    Eclipse设置Tab键缩进4个空格的步骤,也就是按一下Tab键输出四个空格
    Nginx 相关介绍(Nginx是什么?能干嘛?个人觉得写得比较好的文章,转载过来)
  • 原文地址:https://www.cnblogs.com/widsom/p/9117195.html
Copyright © 2011-2022 走看看