学到了有用而实用的东西,没错,就是莫涛大佬的玄学暴力骗分算法,莫队
推荐一篇博文,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;
}