又被太神鄙视了……
虽然题数比较少,但还是纪念一下吧。
同一类问题,计算一个nxt[i]表示i后面出现的第一个位置,离线做,按照右端点排序,扫描到i,把nxt[nxt[i]]减1,nxt[i]加1。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#define maxn 1000010
using namespace std;
struct yts
{
int l,r,id;
}q[maxn];
int a[maxn],nxt[maxn],ans[maxn];
int c[maxn];
int last[maxn];
int n,m,tot,mx;
bool cmp(yts x,yts y)
{
return x.l>y.l;
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int d)
{
for (int i=x;i<=n;i+=lowbit(i)) c[i]+=d;
}
int query(int x)
{
int ans=0;
for (int i=x;i;i-=lowbit(i)) ans+=c[i];
return ans;
}
int main()
{
scanf("%d%d%d",&n,&mx,&m);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=mx;i++) last[i]=n+1;
for (int i=n;i>=1;i--)
{
nxt[i]=last[a[i]];
last[a[i]]=i;
}
nxt[n+1]=n+1;
for (int i=1;i<=m;i++) {scanf("%d%d",&q[i].l,&q[i].r);q[i].id=i;}
sort(q+1,q+m+1,cmp);
int j=n;
for (int i=1;i<=m;i++)
{
while (j && j>=q[i].l) add(nxt[nxt[j]],-1),add(nxt[j--],1);
ans[q[i].id]=query(q[i].r);
}
for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}