• P1972 [SDOI2009]HH的项链


    P1972 [SDOI2009]HH的项链

    题目背景

    题目描述

    HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答……因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。

    输入输出格式

    输入格式:

    第一行:一个整数N,表示项链的长度。

    第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为0 到1000000 之间的整数)。

    第三行:一个整数M,表示HH 询问的个数。

    接下来M 行:每行两个整数,L 和R(1 ≤ L ≤ R ≤ N),表示询问的区间。

    输出格式:

    M 行,每行一个整数,依次表示询问对应的答案。

    输入输出样例

    输入样例#1: 
    6
    1 2 3 4 3 5
    3
    1 2
    3 5
    2 6
    
    输出样例#1: 
    2
    2
    4

    说明

    数据范围:

    对于100%的数据,N <= 500000,M <= 200000。

    ————————————————————————————————————————————————————————————

    code

    听说这是一道莫队入门题,虽然看着数据范围毒瘤,但还是尝试用莫队A掉此题

    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <iostream>
    #include <map>
    #include <queue>
    #include <vector>
    
    const int MAXX = 1000010;
    int n, m, a[MAXX], cnt[MAXX], ans[MAXX], sum;
    
    struct Question {
        int l, r, id, pos;
        bool operator < (const Question &x) const {
            if (pos == x.pos) return r < x.r;
            return pos < x.pos;
        }
    }q[MAXX];
    
    inline int read() {
        int num = 0, f = 1; char ch = getchar();
        while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
        while (isdigit(ch)) {num = num * 10 + ch - '0'; ch = getchar();}
        return num * f;
    }
    
    void Add(int x) {sum += ++cnt[a[x]] == 1 ? 1 : 0;}
    void Del(int x) {sum -= --cnt[a[x]] == 0 ? 1 : 0;}
    
    int main() {
        //freopen("test.in", "r", stdin);
        //freopen("test.out", "w", stdout);
        n = read();
        for (int i = 1; i <= n; ++ i) a[i] = read();
        int Siz = ceil(sqrt(n));
        m = read();
        for (int i = 1; i <= m; ++ i) {
            q[i].l = read(); q[i].r = read();
            q[i].pos = q[i].l / Siz;
            q[i].id = i;
        }
        std::sort(q + 1, q + m + 1);
        int ql = q[1].l, qr = q[1].l - 1;
        for (int i = 1; i <= m; ++ i) {
            while (ql < q[i].l) Del(ql++);
            while (ql > q[i].l) Add(--ql);
            while (qr < q[i].r) Add(++qr);
            while (qr > q[i].r) Del(qr--);
            ans[q[i].id] = sum;
        } 
        for (int i = 1; i <= m; ++ i) printf("%d
    ", ans[i]);
        return 0;
    }

    emmmmm……T掉了两个点

    试图各种卡常,快速读入,快速输出,register,inline,++前缀,循环展开,呼吸新鲜空气等

    // luogu-judger-enable-o2
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("inline")
    #pragma GCC optimize("-fgcse")
    #pragma GCC optimize("-fgcse-lm")
    #pragma GCC optimize("-fipa-sra")
    #pragma GCC optimize("-ftree-pre")
    #pragma GCC optimize("-ftree-vrp")
    #pragma GCC optimize("-fpeephole2")
    #pragma GCC optimize("-ffast-math")
    #pragma GCC optimize("-fsched-spec")
    #pragma GCC optimize("unroll-loops")
    #pragma GCC optimize("-falign-jumps")
    #pragma GCC optimize("-falign-loops")
    #pragma GCC optimize("-falign-labels")
    #pragma GCC optimize("-fdevirtualize")
    #pragma GCC optimize("-fcaller-saves")
    #pragma GCC optimize("-fcrossjumping")
    #pragma GCC optimize("-fthread-jumps")
    #pragma GCC optimize("-funroll-loops")
    #pragma GCC optimize("-fwhole-program")
    #pragma GCC optimize("-freorder-blocks")
    #pragma GCC optimize("-fschedule-insns")
    #pragma GCC optimize("inline-functions")
    #pragma GCC optimize("-ftree-tail-merge")
    #pragma GCC optimize("-fschedule-insns2")
    #pragma GCC optimize("-fstrict-aliasing")
    #pragma GCC optimize("-fstrict-overflow")
    #pragma GCC optimize("-falign-functions")
    #pragma GCC optimize("-fcse-skip-blocks")
    #pragma GCC optimize("-fcse-follow-jumps")
    #pragma GCC optimize("-fsched-interblock")
    #pragma GCC optimize("-fpartial-inlining")
    #pragma GCC optimize("no-stack-protector")
    #pragma GCC optimize("-freorder-functions")
    #pragma GCC optimize("-findirect-inlining")
    #pragma GCC optimize("-fhoist-adjacent-loads")
    #pragma GCC optimize("-frerun-cse-after-loop")
    #pragma GCC optimize("inline-small-functions")
    #pragma GCC optimize("-finline-small-functions")
    #pragma GCC optimize("-ftree-switch-conversion")
    #pragma GCC optimize("-foptimize-sibling-calls")
    #pragma GCC optimize("-fexpensive-optimizations")
    #pragma GCC optimize("-funsafe-loop-optimizations")
    #pragma GCC optimize("inline-functions-called-once")
    #pragma GCC optimize("-fdelete-null-pointer-checks")
    
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <iostream>
    #include <map>
    #include <queue>
    #include <vector>
    #define put putchar('
    ')
    
    const int MAXX = 1000010;
    int n, m, a[MAXX], cnt[MAXX], ans[MAXX], sum;
    
    struct Question {
        int l, r, id, pos;
        bool operator < (const Question &x) const {
            if (pos == x.pos) return r < x.r;
            return pos < x.pos;
        }
    }q[MAXX];
    
    struct FastIO {
        static const int S = 1e7;
        int wpos;
        char wbuf[S];
        FastIO() : wpos(0) {}
        inline int xchar() {
            static char buf[S];
            static int len = 0, pos = 0;
            if (pos == len)
                pos = 0, len = fread(buf, 1, S, stdin);
            if (pos == len) exit(0);
            return buf[pos++];
        }
        inline int xuint() {
            int c = xchar(), x = 0;
            while (c <= 32) c = xchar();
            for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
            return x;
        }
        inline int xint() {
            int s = 1, c = xchar(), x = 0;
            while (c <= 32) c = xchar();
            if (c == '-') s = -1, c = xchar();
            for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
            return x * s;
        }
        inline void xstring(char *s) {
            int c = xchar();
            while (c <= 32) c = xchar();
            for (; c > 32; c = xchar()) * s++ = c;
            *s = 0;
        }
        inline void wchar(int x) {
            if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
            wbuf[wpos++] = x;
        }
        inline void wint(long long x) {
            if (x < 0) wchar('-'), x = -x;
            char s[24];
            int n = 0;
            while (x || !n) s[n++] = '0' + x % 10, x /= 10;
            while (n--) wchar(s[n]);
            wchar('
    ');
        }
        inline void wstring(const char *s) {
            while (*s) wchar(*s++);
        }
        ~FastIO() {
            if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
        }
    } io;
    inline void wr(int x){if (x<0) {putchar('-');wr(-x);return;}if(x>=10)wr(x/10);putchar(x%10+'0');}
    inline void wrn(int x){wr(x);put;}
    
    inline void Add(register int x) {sum += ++cnt[a[x]] == 1 ? 1 : 0;}
    inline void Del(register int x) {sum -= --cnt[a[x]] == 0 ? 1 : 0;}
    
    int main() {
        //freopen("test.in", "r", stdin);
        //freopen("test.out", "w", stdout);
        n = io.xint();
        for (register int i = 1; i <= n; ++ i) {
            a[i] = io.xint();
        }
        register int Siz = ceil(sqrt(n));
        m = io.xint();
        for (register int i = 1; i <= m; ++ i) {
            q[i].l = io.xint(), q[i].r = io.xint();
            q[i].pos = q[i].l / Siz;
            q[i].id = i;
        }
        std::sort(q + 1, q + m + 1);
        register int ql = q[1].l, qr = q[1].l - 1;
        for (register int i = 1; i <= m; ++ i) {
            while (ql < q[i].l) Del(ql++);
            while (ql > q[i].l) Add(--ql);
            while (qr < q[i].r) Add(++qr);
            while (qr > q[i].r) Del(qr--);
            ans[q[i].id] = sum;
        } 
        for (register int i = 1; i <= m; ++ i) {
            wrn(ans[i]);
        }
        return 0;
    }

    卡常失败*N

    QWQ

    看题解用大佬的神奇主席树终结此题

    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <iostream>
    #include <map>
    #include <queue>
    #include <vector>
    
    typedef long long LL;
    
    const int MAXX = 10000010;
    int n, m;
    int cnt, lst[MAXX], tp[MAXX], rot[MAXX];
    
    struct PTree {
        int l, r, sum;
    }t[MAXX];
    
    inline int read() {
        int num = 0, f = 1; char ch = getchar();
        while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
        while (isdigit(ch)) {num = num * 10 + ch - '0'; ch = getchar();}
        return num * f;
    }
    
    void Build(int &u, int x, int l, int r) {
        t[++cnt] = t[u]; 
        u = cnt; ++ t[u].sum;
        if (l == r) return ;
        int mid = (l + r) >> 1;
        if (x <= mid) Build(t[u].l, x, l, mid);
        else Build(t[u].r, x, mid + 1, r);
    }
    
    int query(int i, int j, int q, int l, int r) {
        if (r <= q) return t[j].sum - t[i].sum;
        int mid = (l + r) >> 1, temp = query(t[i].l, t[j].l, q, l, mid);
        if (mid < q) temp += query(t[i].r, t[j].r, q, mid + 1, r);
        return temp;
    }
    
    int main() {
        n = read(); int x, l, r;
        for (int i = 1; i <= n; ++ i) {
            x = read();
            lst[i] = tp[x];
            tp[x] = i;
        }
        rot[0] = 0;
        for (int i = 1; i <= n; ++ i) {
            rot[i] = rot[i - 1];
            Build(rot[i], lst[i], 0, n);
        }
        m = read();
        for (int i = 1; i <= m; ++ i) {
            l = read(), r = read();
            printf("%d
    ", query(rot[l - 1], rot[r], l - 1, 0, n));
        }
        return 0;
    }
  • 相关阅读:
    JavaScript constructor prototyoe
    bootstrap固定响应式导航
    跨浏览器事件处理程序
    原生JS实现字符串分割
    关于css里的class和id
    js动态创建表格方法
    关于css的默认宽度
    js字符串大小写转换
    C++类的一个重要成员:静态成员(二)——静态成员的定义
    C++ 类的一个重要成员:静态成员(一)
  • 原文地址:https://www.cnblogs.com/hkttg/p/9416268.html
Copyright © 2020-2023  润新知