2 3 1 1 4 2 1 2 2 3 5 1 1 2 1 3 3 1 5 2 4 3 5
1 5 6 3 6
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
typedef long long LL;
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
const int maxn=30005;
const int maxm=100005;
LL sum[maxn<<2],a[maxn],ans[maxm];
struct node{
int l,r,index;
bool operator<(const node a)const
{
return r<a.r;
}
}p[maxm];//保存每次询问
map<LL,int>hash;
int t,n,m;
void pushup(int rs)
{
sum[rs]=sum[rs<<1]+sum[rs<<1|1];
}
void build(int rs,int l,int r)
{
sum[rs]=0;
if(l==r) return ;
int mid=(l+r)>>1;
build(rs<<1,l,mid);
build(rs<<1|1,mid+1,r);
}
void update(int rs,LL c,int x,int l,int r)
{
if(l==r)
{
sum[rs]=c;
return ;
}
int mid=(l+r)>>1;
if(x<=mid) update(rs<<1,c,x,l,mid);
else update(rs<<1|1,c,x,mid+1,r);
pushup(rs);
}
LL query(int rs,int x,int y,int l,int r)
{
if(l>=x&&r<=y)
return sum[rs];
int mid=(l+r)>>1;
LL res=0;
if(x<=mid) res+=query(rs<<1,x,y,l,mid);
if(y>mid) res+=query(rs<<1|1,x,y,mid+1,r);
return res;
}
void solve()
{
int pos=1;
REPF(i,1,m)
{
while(p[i].r>=pos)
{
if(hash[a[pos]])//若此值出现过,原位置上值更新为0.
update(1,0,hash[a[pos]],1,n);
hash[a[pos]]=pos;//更新当前值的位置
update(1,a[pos],pos,1,n);pos++;
}
// cout<<"666 "<<query(1,1,2,1,n)<<endl;
ans[p[i].index]=query(1,p[i].l,p[i].r,1,n);
}
}
int main()
{
scanf("%d",&t);
int x,y;
while(t--)
{
hash.clear();
scanf("%d",&n);
build(1,1,n);
REPF(i,1,n) scanf("%I64d",&a[i]);
scanf("%d",&m);
REPF(i,1,m)
{
scanf("%d%d",&p[i].l,&p[i].r);
p[i].index=i;
}
sort(p+1,p+1+m);
solve();
REPF(i,1,m)
printf("%I64d\n",ans[i]);
}
return 0;
}
原文:http://blog.csdn.net/u013582254/article/details/41098929