P1972被卡2个点,这种做法真的过不去吗,还是说有什么玄学优化
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N=1000010,M=1000010,S=1000010;
int n,m,len;
int w[N],ans[M],cnt[S];
struct Query{
int id,l,r;
bool operator <(const Query &Q)const{
int i=l/len,j=Q.l/len;
if(i!=j) return i<j;
return i&1?r<Q.r:r>Q.r;
}
}q[M];
void read(int &x){
x=0;int f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
x*=f;
}
void add(int x,int &res){
if(!cnt[x]) res++;
cnt[x]++;
}
void del(int x,int &res){
cnt[x]--;
if(!cnt[x]) res--;
}
int main(){
read(n);
for(int i=1;i<=n;i++) read(w[i]);
read(m);
len=sqrt((double)n*n/m);
for(int i=0;i<m;i++){
int l,r;
read(l),read(r);
q[i]={i,l,r};
}
sort(q,q+m);
for(int k=0,i=0,j=1,res=0;k<m;k++){
int id=q[k].id,l=q[k].l,r=q[k].r;
while(i<r) add(w[ ++i ],res);
while(i>r) del(w[ i-- ],res);
while(j<l) del(w[ j++ ],res);
while(j>l) add(w[ --j ],res);
ans[id]=res;
}
for(int i=0;i<m;i++) printf("%d\n",ans[i]);
return 0;
}