• 牛客网暑期ACM多校训练营(第一场)J Different Integers


    题目链接:https://www.nowcoder.com/acm/contest/139/J

    解题心得:

    • 这个暑假第一场多校啊,第一个签到题莫队算法,心梗。
    • 题意是叫你输出1-l,r-n有多少个不同的数,可以先将所有的数的个数处理出来 ,然后减去区间 [l+1, r-1]中数的个数,区间内的答案就是总的个数 - 区间内被减成0的个数,这样区间就可以用莫队算法维护。
    • 题居然卡set和map,这么毒的么。
    //
    //      ┏┛ ┻━━━━━┛ ┻┓
    //      ┃       ┃
    //      ┃   ━   ┃
    //      ┃ ┳┛   ┗┳ ┃
    //      ┃       ┃
    //      ┃   ┻   ┃
    //      ┃       ┃
    //      ┗━┓   ┏━━━┛
    //        ┃   ┃   神兽保佑
    //        ┃   ┃   代码无BUG!
    //        ┃   ┗━━━━━━━━━┓
    //        ┃           ┣┓
    //        ┃             ┏┛
    //        ┗━┓ ┓ ┏━━━┳ ┓ ┏━┛
    //          ┃ ┫ ┫   ┃ ┫ ┫
    //          ┗━┻━┛   ┗━┻━┛
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+100;
     
    struct Query{
        int l, r, pos, ans;
    }q[maxn];
     
    int n,m,unit, tot, ans;
    int num[maxn],B[maxn], maps[maxn];
     
    bool cmp1(Query x, Query y) {
        if(B[x.l] == B[y.l])
            return x.r < y.r;
        return x.l < y.l;
    }
     
    bool cmp2(Query x, Query y) {
        return x.pos < y.pos;
    }
     
    void init() {
        ans = 0;
        unit = (int) sqrt(n);
        tot = 0;
        memset(maps, 0, sizeof(maps));
        for(int i=1;i<=n;i++) {
            scanf("%d",&num[i]);
            if(maps[num[i]] == 0)
                tot++;
            maps[num[i]]++;
            B[i] = i/unit + 1;
        }
        for(int i=0;i<m;i++) {
            scanf("%d%d",&q[i].l, &q[i].r);
            q[i].l++;
            q[i].r--;
            q[i].pos = i;
        }
        sort(q, q+m, cmp1);
    }
     
    void add(int pos, int va) {
        if(maps[num[pos]] + va == 0) {
            ans++;
        }
        if(maps[num[pos]] == 0)
            ans--;
        maps[num[pos]] += va;
    }
     
    void Modui() {
        int l = 1, r = 0;
        for(int i=0;i<m;i++) {
            if(q[i].l > q[i].r) {
                q[i].ans = tot;
                continue;
            }
            while(l < q[i].l)
                add(l++, 1);
            while(l > q[i].l)
                add(--l, -1);
            while(r < q[i].r)
                add(++r, -1);
            while(r > q[i].r)
                add(r--, 1);
     
            q[i].ans = tot - ans;
        }
    }
     
    int main() {
        while(scanf("%d%d",&n,&m) != EOF) {
            init();
            Modui();
            sort(q, q+m, cmp2);
            for(int i=0;i<m;i++)
                printf("%d
    ", q[i].ans);
        }
        return 0;
    }
  • 相关阅读:
    inflate
    【Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性
    安卓延时执行代码
    Listview控件
    安卓的progress
    android studio的弹出层
    解决mysql的日志文件过大的问题
    linux查文件大小
    乔坟往事-姑妄言之
    乔坟往事-村里人家
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9428665.html
Copyright © 2020-2023  润新知