https://www.nowcoder.com/acm/contest/139/J
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+500;
typedef struct node{
int l,r,No;
}node;
int cmp(node a, node b){
return (a.r==b.r&&a.l<b.l)||a.r<b.r;
}
node q[N];
int n,m,k,tmp,c[N],a[N],vis[N],ans[N];
int lowbit(int x){return x&(-x);}
void update(int x,int val=1){for(;x<=2*n;c[x]+=val,x+=lowbit(x));}
int getsum(int x){ int ret=0;for(;x>0;ret+=c[x],x-=lowbit(x));return ret;}
int main()
{
while(~scanf("%d%d",&n,&m)){
memset(q,0,sizeof(q));
memset(c,0,sizeof(c));
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++){scanf("%d",&a[i]);a[n+i]=a[i];}
for(int i=1;i<=m;i++){
scanf("%d%d",&q[i].l,&q[i].r);q[i].No=i;
tmp=q[i].r;q[i].r=q[i].l+n;q[i].l=tmp;
}
sort(q+1, q+1+m,cmp);
int L=1;
for(int i=1;i<=m;i++){
for(int j=L;j<=q[i].r;j++){
if(vis[a[j]]){
update(vis[a[j]],-1);
}
update(j,1);
vis[a[j]]=j;
}
L=q[i].r+1;
ans[q[i].No]=getsum(q[i].r)-getsum(q[i].l-1);
}
for(int i=1;i<=m;i++){
printf("%d\n",ans[i]);
}
}
return 0;
}
用莫队算法会超时,但我还是贴出来。如果预处理过的莫队还是能过。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+50;
void read(int &ans){
int x=0,f=1;char c=getchar();
for( ; !isdigit(c); c=getchar()) { if(c=='-') f=-1;}
for( ; isdigit(c); c=getchar()) {x=x*10+c-'0';}
ans=f*x;
}
int unit,n,m,tmp;
int num[N],a[N],ans[N];
typedef struct node{
int L,R,No;
}node;
int cmp(node a,node b){
return a.L/unit!=b.L/unit ? a.L/unit <b.L/unit :a.R<b.R;
}
node Q[N];
void add(int x){
if(num[x]==0) tmp++;
num[x]++;
}
void del(int x){
num[x]--;
if(num[x]==0) tmp--;
}
void solve(){
memset(num,0,sizeof(num));
unit=(int)pow(n,0.67);
sort(Q+1,Q+m+1,cmp);
int L=1,R=0;
tmp=0;
for(int i=1;i<=m;i++){
while(R<Q[i].R) { add(a[++R]); }
while(R>Q[i].R) { del(a[R--]); }
while(L<Q[i].L) { del(a[L++]); }
while(L>Q[i].L) { add(a[--L]); }
ans[Q[i].No]=tmp;
}
for(int i=1;i<=m;i++){
printf("%d\n",ans[i]);
}
}
int main()
{
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;i++) {read(a[i]);a[i+n]=a[i];}
for(int i=1;i<=m;i++){
read(Q[i].L);
read(Q[i].R);
Q[i].No=i;
tmp=Q[i].R;
Q[i].R=Q[i].L+n;
Q[i].L=tmp;
}
//sort(Q+1,Q+m+1);
//for(int i=1;i<=m;i++)printf("%d %d\n",Q[i].L,Q[i].R);
solve();
}
return 0;
}