题目背景
无
题目描述
HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答……因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。
输入输出格式
输入格式:
第一行:一个整数N,表示项链的长度。
第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为0 到1000000 之间的整数)。
第三行:一个整数M,表示HH 询问的个数。
接下来M 行:每行两个整数,L 和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
输出格式:
M 行,每行一个整数,依次表示询问对应的答案。
输入输出样例
输入样例#1:
6
1 2 3 4 3 5
3
1 2
3 5
2 6
输出样例#1:
2
2
4
说明
数据范围:
对于100%的数据,N <= 50000,M <= 200000。
题解:莫队
错因:
void add(int x){
if(apper[b[x]]==0){
ans++;
} apper[b[x]]++;
}
把apper[b[x]]放到if里面了。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #define maxn 50005 #define maxm 1000005 using namespace std; int n,ans,m,b[maxn],apper[maxm]; struct Query{ int l,r,ans,pos,id; }a[maxn<<2]; inline int read(){ char ch=getchar();int x=0,f=1; for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0'; return x*f; } bool cmp(Query a,Query b){ if(a.pos==b.pos)return a.r<b.r; return a.pos<b.pos; } bool cmp_id(Query a,Query b){ return a.id<b.id; } void add(int x){ if(apper[b[x]]==0){ ans++; } apper[b[x]]++; } void del(int x){ apper[b[x]]--; if(apper[b[x]]==0)ans--; } void slove(){ int L=1,R=0; for(int i=1;i<=m;i++){ while(L<a[i].l)del(L++); while(L>a[i].l)add(--L); while(R<a[i].r)add(++R); while(R>a[i].r)del(R--); a[i].ans=ans; } } int main(){ n=read(); for(int i=1;i<=n;i++)b[i]=read(); int size=(int)sqrt(n); m=read(); for(int i=1;i<=m;i++){ a[i].l=read();a[i].r=read(); a[i].id=i;a[i].pos=(a[i].l-1)/size+1; } sort(a+1,a+m+1,cmp); slove(); sort(a+1,a+m+1,cmp_id); for(int i=1;i<=m;i++)printf("%d ",a[i].ans); return 0; }