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 "\n" 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\n", 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 "\n" 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\n", ans[i]); }