这题算是莫队基础题,然鹅我基础都不会(wtcl
#include<bits/stdc++.h>
#define kkk 300005
using namespace std;
int n,a[kkk],f[kkk],ans[kkk],cnt[kkk],belong[kkk];
int q,sq,now;
struct query{
int l,r,num;
}qst[kkk];//用于记录问题,不然排序之后顺序就乱了
bool cmp(query p, query q){
return (f[p.l]^f[q.l])?f[p.l]<f[q.l]:((f[p.l]&1)?p.r<q.r:p.r>q.r);
}//排序函数,莫队按奇偶性玄学优化
void add(int tmp){//增加一个数
if(!cnt[a[tmp]])++now;//如果没出现过总数++
++cnt[a[tmp]];//出现次数++
}
void del(int tmp){//同上
--cnt[a[tmp]];
if(!cnt[a[tmp]])--now;
}
/*void print1(){
for(int i=1;i<=sqrt(n)+10;i++){
cout<<f[i]<<" ";
}
for(int i=1;i<=sqrt(n)+10;i++){
cout<<a[i]<<" ";
}
for(int i=1;i<=sqrt(n)+10;i++){
cout<<cnt[i]<<" ";
}
cout<<endl;
}
*/
//上面是调试用的
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);//黑科技cin,cout加速
cin>>n;
sq=sqrt(n);//分块
for(int i=1;i<=n;i++){
f[i]=(i-1)/sq+1;//分到哪个块里面
cin>>a[i];
}
cin>>q;
for(int i=1;i<=q;i++){
cin>>qst[i].l>>qst[i].r;
qst[i].num=i;//记录是第几个问题
}
/*print1();
print2();
*/
sort(qst+1,qst+q+1,cmp);//排序
int l=1,r=0;
for(int i=1;i<=q;i++){
int ll=qst[i].l;
int rr=qst[i].r;
//以下都是莫队基本操作
while(l<ll)del(l++);
while(l>ll)add(l--);
while(r<rr)add(++r);
while(r>rr)del(r--);
ans[qst[i].num]=now;
}
for(int i=1;i<=q;i++){
cout<<ans[i]<<endl;
}//输出
return 0;
}
小蒟蒻求助啊啊啊,第一个点直接WA掉,调疯了。。
(来自蒟蒻的呐喊