牛客网暑期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\n", q[i].ans);
    }
    return 0;
}

 

posted @ 2018-08-06 09:56  GoldenFingers  阅读(178)  评论(0编辑  收藏  举报