离线处理,注意排序方式
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#define ll long long
const int maxn=320010;
const int Block=sqrt(maxn);
const int tt=1;//数字出现的最少次数
using namespace std;
struct node
{
int id;
int l,r;
}pos[200010];
int n,q,a[maxn],cnt[1000100],answer=0,l,r,ans[200010];
bool cmp(node a,node b)
{
if(a.l/Block!=b.l/Block)
return a.l/Block<b.l/Block;
return a.r<b.r;
}
void add(int positoin)
{
cnt[a[positoin]]++;
if(cnt[a[positoin]]==tt)
answer++;
}
void Remove(int positoin)
{
cnt[a[positoin]]--;
if(cnt[a[positoin]]==tt-1)
answer--;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%d %d",&pos[i].l,&pos[i].r);
pos[i].id=i;
}
sort(pos+1,pos+q+1,cmp);
int cl=1,cr=1;
for(int i=1;i<=q;i++)
{
l=pos[i].l;r=pos[i].r;
while(cl<l) {
Remove(cl);
cl++;
}
while(cl>l) {
add(cl-1);
cl--;
}
while(cr<=r) {
add(cr);
cr++;
}
while(cr>r+1)
{
Remove(cr-1);
cr--;
}
ans[pos[i].id]=answer;
}
for(int i=1;i<=q;i++)
printf("%d\n",ans[i]);
return 0;
}
当然线段树也可以解决
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<map>
#include<algorithm>
#include<cmath>
#define eps 1e-8
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int a[maxn];
struct node1
{
int l,r,id;
}q[maxn<<2];
ll e[maxn<<2],sum[maxn<<2];
bool cmp(node1 a,node1 b)
{
return a.r<b.r;
}
void pushup(int cur)
{
e[cur]=e[cur<<1]+e[cur<<1|1];
}
void build(int l,int r,int cur)
{
e[cur]=0;
if(l==r)
return;
int m=l+r>>1;
build(l,m,cur<<1);
build(m+1,r,cur<<1|1);
//pushup(cur);
}
void update(int l,int r,int val,int cur,int pos)
{
if(l==r)
{
if(val==0)
e[cur]=val;
else e[cur]=1;
return;
}
int m=l+r>>1;
if(pos<=m)update(l,m,val,cur<<1,pos);
else update(m+1,r,val,cur<<1|1,pos);
pushup(cur);
}
ll query(int l,int r,int cur,int pl,int pr)
{
if(pl<=l&&r<=pr)
{
return e[cur];
}
ll ans=0;
int m=l+r>>1;
if(pl<=m) ans+=query(l,m,cur<<1,pl,pr);
if(pr>m)ans+=query(m+1,r,cur<<1|1,pl,pr);
return ans;
}
map<int,int>mp;
int main()
{
int T;
//scanf("%d",&T);
// while(T--)
//{
mp.clear();
int n,m;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
build(1,n,1);
scanf("%d",&m);
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 pos=1;
for(int i=1;i<=m;i++)
{
while(q[i].r>=pos)
{
if(mp[a[pos]])
update(1,n,0,1,mp[a[pos]]);
mp[a[pos]]=pos;
update(1,n,a[pos],1,pos);
pos++;
}
sum[q[i].id]=query(1,n,1,q[i].l,q[i].r);
}
for(int i=1;i<=m;i++)
{
printf("%lld\n",sum[i]);
}
//}
return 0;
}