BZOJ 1878 [SDOI2009]HH的項鍊(莫隊演算法)
阿新 • • 發佈:2020-08-07
題意:給出長度為n的序列a,給出m組詢問,問L-R區間的數字種類個數,離線詢問。n<2e5,a[i]<1e6
題解:莫隊模板,注意就是用奇偶性排序可加快,和block=n/sqrt(m*2/3)。複雜度:nlogn
#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++) #definelowbit(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(intx){ 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; }