zoukankan      html  css  js  c++  java
  • 「题解」洛谷 CF1000F One Occurrence

    题目

    CF1000F One Occurrence

    简化题意

    一个长为 (n) 的序列,每次询问一个区间内只出现过一次的数是什么。

    思路

    莫队 + 大力卡常 + O3。

    考虑莫队怎么维护只出现过一次的数,开个栈,栈中元素都是只出现过一次的,如果一个数原本出现过一次在一次操作后不再是只出现一次了,就把他在栈中的位置替换成栈顶的元素,清空一下各种标记啥的。最后栈中元素都是只出现过一次的。

    用到的卡常小技巧

    • 奇偶性优化
    • 块大小开 (largefrac{n}{sqrt{m}})
    • O(3)

    Code

    #pragma GCC optimize (3)
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #define MAXN 500001
    
    inline void read(int &T) {
        int x = 0;
        bool f = 0;
        char c = getchar();
        while (c < '0' || c > '9') {
            if (c == '-') f = !f;
            c = getchar();
        }
        while (c >= '0' && c <= '9') {
            x = x * 10 + c - '0';
            c = getchar();
        }
        T = f ? -x : x;
    }
    
    void write(int x) {
        if (x / 10) write(x / 10);
        putchar(x % 10 + '0');
    }
    
    int n, m, top, a[MAXN], s[MAXN], pos[MAXN];
    int sqrn, num[MAXN], cnt[MAXN], ans[MAXN];
    struct query {
        int x, y, id;
        friend bool operator < (query q1, query q2) {
            return (num[q1.x] ^ num[q2.x]) ? num[q1.x] < num[q2.x] : (num[q1.x] & 1) ? q1.y < q2.y : q1.y > q2.y;
        }
    }q[MAXN];
    
    void add(int x) {
        ++cnt[x];
        if (cnt[x] == 1) {
            s[++top] = x, pos[x] = top;
        }
        else if (cnt[x] == 2) {
            s[pos[x]] = s[top];
            pos[s[top]] = pos[x];
            s[top--] = pos[x] = 0;
        }
    }
    
    void del(int x) {
        --cnt[x];
        if (cnt[x] == 1) {
            s[++top] = x, pos[x] = top;
        }
        else if (!cnt[x]) {
            s[pos[x]] = s[top];
            pos[s[top]] = pos[x];
            s[top--] = pos[x] = 0;
        }
    }
    
    int main() {
        read(n);
        for (int i = 1; i <= n; ++i) read(a[i]);
        read(m), sqrn = n / sqrt(m);
        for (int i = 1; i <= n; ++i) num[i] = (i - 1) / sqrn + 1;
        for (int i = 1; i <= m; ++i) {
            read(q[i].x), read(q[i].y);
            q[i].id = i;
        }
        std::sort(q + 1, q + m + 1);
        int l = 1, r = 1; add(a[l]);
        for (int i = 1; i <= m; ++i) {
            while (l > q[i].x) add(a[--l]);
            while (r < q[i].y) add(a[++r]);
            while (l < q[i].x) del(a[l++]);
            while (r > q[i].y) del(a[r--]);
            ans[q[i].id] = s[top];
        }
        for (int i = 1; i <= m; ++i) {
            write(ans[i]);
            puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    Android手势锁实现
    网页模板pug基本语法
    React入门看这篇就够了
    我曾站在离你最近的天涯
    一文看懂浏览器事件循环
    Vi编辑网卡
    2019.6.11_MySQL进阶二:主键与外键
    2019.6.13_笔试题目及答案
    2019.6.13_MySQL简单命令的使用
    2019.6.13_SQL语句中----删除表数据drop、truncate和delete的用法
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13589955.html
Copyright © 2011-2022 走看看