SP3267 DQUERY - D-query
学到了有用而实用的东西,没错,就是莫涛大佬的玄学暴力骗分算法,莫队
推荐一篇博文,tj也是从这嫖的
顺便推一下莫涛大佬的逼乎知乎
#include <cstdio> #include <cstring> #include <cmath> #include <iostream> #include <algorithm> using namespace std; #define maxn 1010000 #define maxb 1010 int aa[maxn],cnt[maxn],belong[maxn]; int n,m,size,bnum,now,ans[maxn]; struct query { int l; int r; int id; }q[maxn]; int cmp(query a, query b) { return (belong[a.l] ^ belong[b.l]) ? belong[a.l] < belong[b.l] : ((belong[a.l] & 1) ? a.r < b.r : a.r > b.r); } void add(int pos) { if(!cnt[aa[pos]]) ++now; ++cnt[aa[pos]]; } void del(int pos) { --cnt[aa[pos]]; if(!cnt[aa[pos]]) --now; } #define isdigit(x) ((x) >= '0' && (x) <= '9') int read() { int res = 0; char c = getchar(); while(!isdigit(c)) c = getchar(); while(isdigit(c)) res = (res << 1) + (res << 3) + c - 48, c = getchar(); return res; } void printi(int x) { if(x / 10) printi(x / 10); putchar(x % 10 + '0'); } int main() { scanf("%d", &n); size = sqrt(n); bnum = ceil((double)n/size); for(int i=1;i<=bnum;++i) for(int j=(i-1)*size+1;j<=i*size;j++) belong[j]=i; for(int i=1;i<=n;i++) aa[i]=read(); m=read(); for(int i=1;i<=m;i++) { q[i].l=read(); q[i].r=read(); q[i].id=i; } sort(q+1,q+m+1,cmp); int l=1,r=0; for(int i=1;i<=m;++i){ 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].id]=now; } for(int i=1;i<=m;++i) printf("%d\n",ans[i]); return 0; }