Description
萧芸斓是Z国的公主,平时的一大爱好是采花。
今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花。花园足够大,容纳了
Input
第一行四个空格隔开的整数
Output
共
Sample Input
5 3 5
1 2 2 3 1
1 5
1 2
2 2
2 3
3 5
Sample Output
2
0 0 1 0
样例说明
询问
询问
询问
询问
询问
HINT
数据范围
对于
Source
思路
离线操作,从前往后扫一遍,当访问到一个位置
代码
#include <cstdio>
#include <algorithm>
const int maxn=1000000;
int n;
struct data
{
int left,right,id;
};
struct segment_tree//树状数组
{
int val[maxn+10];
inline int lowbit(int x)
{
return x&(-x);
}
inline int add(int pos,int adv)
{
while(pos<=n)
{
val[pos]+=adv;
pos+=lowbit(pos);
}
return 0;
}
inline int sum(int pos)
{
int res=0;
while(pos)
{
res+=val[pos];
pos-=lowbit(pos);
}
return res;
}
};
data d[maxn+10];
int c,m,last[maxn+10],llast[maxn+10],color[maxn+10],now,ans[maxn+10];
segment_tree st;
const bool cmpa(const data &a,const data &b)
//按区间右断点排序,方便后面的处理
{
return a.right<b.right;
}
inline int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
int main()
{
n=read();
c=read();
m=read();
for(register int i=1; i<=n; ++i)
{
color[i]=read();
}
for(register int i=1; i<=m; ++i)
{
d[i].left=read();
d[i].right=read();
d[i].id=i;
}
std::sort(d+1,d+m+1,cmpa);
now=1;
for(register int i=1; i<=n; ++i)
{
if(last[color[i]]!=llast[color[i]])
{
if(llast[color[i]])//防止数组越界
{
st.add(llast[color[i]],-1);
}
if(last[color[i]])
{
st.add(last[color[i]],1);
}
}
while((now<=m)&&(d[now].right==i))//寻找右端点为i的点
{
ans[d[now].id]=st.sum(d[now].right)-st.sum(d[now].left-1);
++now;
}
llast[color[i]]=last[color[i]];//更新llast和last
last[color[i]]=i;
}
for(register int i=1; i<=m; ++i)
{
printf("%d\n",ans[i]);
}
return 0;
}