莫队基础

//http://www.spoj.com/problems/DQUERY/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int MAXN = 30009;
const int MAXM = 1000009;
const int MAXQ = 200009;
int n, q, sum, B, a[MAXN], ans[MAXQ], cnt[MAXM];
struct Lu
{
    int lef, rig, id;
    bool operator < (const Lu &p)const {
        if ((lef - 1) / B == (p.lef - 1)/B) return rig < p.rig;
        return (lef - 1) / B < (p.lef - 1) / B;
    }
} L[MAXQ];
void add(int x)
{
    ++cnt[a[x]];
    if (cnt[a[x]] == 1) ++sum;
}
void remove(int x)
{
    --cnt[a[x]];
    if (cnt[a[x]] == 0) --sum;
}
int main()
{
    memset(cnt, 0, sizeof(cnt));
    scanf("%d", &n);
    B = sqrt(n);
    for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    scanf("%d", &q);
    for (int i = 1; i <= q; ++i) {
        scanf("%d %d", &L[i].lef, &L[i].rig);
        L[i].id = i;
    }
    sort(L + 1, L + 1 + q);
    sum = 1;
    int LL = 1, RR = 1;
    cnt[a[1]]=1;
    for (int i = 1; i <= q; ++i) {
        while (LL < L[i].lef) remove(LL++);
        while (LL > L[i].lef) add(--LL);
        while (RR > L[i].rig) remove(RR--);
        while (RR < L[i].rig) add(++RR);
        ans[L[i].id] = sum;
    }
    for (int i = 1; i <= q; ++i) printf("%d\n", ans[i]);
    return 0;
}





//带修改莫队  
// B可设为 sqrt(n) * 10  或其他值。
http://www.lydsy.com/JudgeOnline/problem.php?id=2120
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 10009;
const int MAXM = 1000009;
int n, q, sum, B, a[MAXN], b[MAXN], cnt[MAXM], change[MAXN][3], ans[MAXN];
int LL = 1, RR = 1, TT = 0;
struct Lu
{
    int lef, rig, tim, id;
    bool operator < (const Lu &p)const {
        if ((lef - 1 / B == (p.lef - 1) / B)) {
            if ((rig - 1) / B == (p.rig - 1) / B) return tim < p.tim;
            return (rig - 1) / B < (p.rig - 1) / B;
        }
        return (lef - 1) / B < (p.lef - 1) / B;
    }
} L[MAXN];
inline bool bound(int x) { return x >= LL && x <= RR; }
inline void remove(int x)
{
    --cnt[a[x]];
    if (cnt[a[x]] == 0) --sum;
}
inline void add(int x)
{
    ++cnt[a[x]];
    if(cnt[a[x]] == 1) ++sum;
}
inline void update(int x, int y)
{
    if (x >= LL && x <= RR) {
        --cnt[a[x]];
        if (cnt[a[x]] == 0) --sum;
        if (cnt[y] == 0) ++sum;
        ++cnt[y];
    }
    a[x] = y;
}
int main()
{
    scanf("%d %d", &n, &q);
    B = pow(n, 2 / 3);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
        b[i] = a[i];
    }
    char ch[2];
    int pp = 0, p = 0;
    for (int i = 1; i <= q; ++i) {
        scanf("%s", ch);
        if (ch[0] == 'Q') {
            ++p;
            scanf("%d %d", &L[p].lef, &L[p].rig);
            L[p].tim = pp;
            L[p].id = p;
        } else {
            ++pp;
            scanf("%d %d", &change[pp][0], &change[pp][1]);
            change[pp][2] = b[change[pp][0]];
            b[change[pp][0]] = change[pp][1];
        }
    }
    sort(L + 1, L + 1 + p);
    memset(cnt, 0, sizeof(cnt));
    cnt[a[1]] = 1;
    sum = 1;
    for (int i = 1; i <= q - pp; ++i) {
        while (TT < L[i].tim) { ++TT; update(change[TT][0], change[TT][1]); }
        while (TT > L[i].tim) { update(change[TT][0], change[TT][2]); --TT; }
        while (LL < L[i].lef) remove(LL++);
        while (LL > L[i].lef) add(--LL);
        while (RR > L[i].rig) remove(RR--);
        while (RR < L[i].rig) add(++RR);
        ans[L[i].id] = sum;
    }
    for (int i = 1; i <= p; ++i) printf("%d\n", ans[i]);
    return 0;
}

 

posted @ 2018-04-10 16:53  luckilzy  阅读(352)  评论(0编辑  收藏  举报