BZOJ 1878 [SDOI2009]HH的项链(莫队算法/树状数组)

题意:给出长度为n的序列a,给出m组询问,问L-R区间的数字种类个数,离线询问。n<2e5,a[i]<1e6

题解:莫队模板,注意就是用奇偶性排序可加快,和block=n/sqrt(m*2/3)。复杂度:n*sqrt(n)

   或者直接树状数组维护前缀和(颜色的总数),并用last数组标记上一个出现该颜色的位置,按r从小到大query,复杂度:n*logn

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define fre freopen("C:\in.txt", "r", stdin)
#define _for(i,a,b) for(int i=a; i< b; i++)
#define _rep(i,a,b) for(int i=a; i<=b; i++)
#define lowbit(a) ((a)&-(a))
#define inf 0x3f3f3f3f
#define endl "
"
using namespace std;
typedef long long ll;
template <class T>
void read(T &x)
{
    char c; bool op=0;
    while(c=getchar(), c<'0'||c>'9') if(c=='-') op=1;
    x=c-'0';
    while(c=getchar(), c>='0'&&c<='9') x=x*10+c-'0';
    if(op) x=-x;
}

const int maxn=5e5+5;
int T, n, m, a[maxn];
int res, num[1000005], ans[maxn]; //这里WA一次,a【i】的范围
struct Node{
    int l, r, idx;
}q[maxn];
int block;

bool cmp(Node x, Node y){
    return (x.l/block)^(y.l/block)? x.l<y.l : (((x.l/block)&1)? x.r<y.r : x.r>y.r);
}

void add(int x){
    if(!num[a[x]]) res++;
    num[a[x]]++;
}

void del(int x){
    num[a[x]]--;
    if(!num[a[x]]) res--;
}

int main()
{
    //read(T);
    T=1;
    while(T--)
    {
        read(n);
        memset(num, 0, sizeof(num));
        res=0;
        _rep(i, 1, n) read(a[i]);
        read(m);
        _rep(i, 1, m) read(q[i].l), read(q[i].r), q[i].idx=i;
        block=n/sqrt(m*2/3);
        sort(q+1, q+1+m, cmp);
        int l=0, r=0;
        _rep(i, 1, m){
            int ql=q[i].l, qr=q[i].r;
            while(l<ql) del(l++);
            while(l>ql) add(--l);
            while(r<qr) add(++r);
            while(r>qr) del(r--);
            ans[q[i].idx]=res;
        }
        _rep(i, 1, m) printf("%d
", ans[i]);
    }
    return 0;
}
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define fre freopen("C:\in.txt", "r", stdin)
#define _for(i,a,b) for(int i=a; i< b; i++)
#define _rep(i,a,b) for(int i=a; i<=b; i++)
#define lowbit(a) ((a)&-(a))
#define inf 0x3f3f3f3f
#define endl "
"
using namespace std;
typedef long long ll;
template <class T>
void read(T &x)
{
    char c; bool op=0;
    while(c=getchar(), c<'0'||c>'9') if(c=='-') op=1;
    x=c-'0';
    while(c=getchar(), c>='0'&&c<='9') x=x*10+c-'0';
    if(op) x=-x;
}

const int maxn=1e6+5;
int n, m, a[maxn], tree[maxn], last[maxn], ans[maxn];
struct Node{
    int l, r, idx;
    bool operator < (const Node &x) const{
        return r<x.r;
    }
}q[maxn];

void add(int i, int x){
    for(; i<=n; i+=lowbit(i)) tree[i]+=x;
}
int query(int i){
    int res=0;
    for(; i>0; i-=lowbit(i)) res+=tree[i];
    return res;
}

int main()
{
    read(n);
    _rep(i, 1, n) read(a[i]);
    read(m);
    _rep(i, 1, m) read(q[i].l), read(q[i].r), q[i].idx=i;
    sort(q+1, q+1+m);
    int p=1;
    _rep(i, 1, n){
        if(last[a[i]]) add(last[a[i]], -1);
        add(i, 1);
        last[a[i]]=i;
        while(q[p].r==i){
            int l=q[p].l, r=q[p].r;
            ans[q[p].idx]=query(r)-query(l-1);
            p++;
        }
    }
    _rep(i, 1, m) printf("%d
", ans[i]);
}
原文地址:https://www.cnblogs.com/Yokel062/p/13454970.html