Process the query offline, that is, record all the queries first.
Map the current value to a subscript using map. If the current value has been mapped before, cancel the record at the previous position in the tree array.
Add the current value to the current position, so that you can update and query each query, and record the results offline.
View Code
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
const int maxn = 50010;
__int64 c[maxn];
struct node{
int l,r,id;
}p[200010];
map<int,int> hash;
int lowbit(int x){
return x&-x;
}
void update(int x,int d){
for(;x<maxn;x+=lowbit(x))
c[x]+=d;
}
__int64 sum(int x){
__int64 ans=0;
for(;x>0;x-=lowbit(x))
ans+=c[x];
return ans;
}
int cmp(node a,node b){
return a.r<b.r;
}
int a[maxn];
__int64 ans[200010];
int main()
{
int t,i,j,l,r,n;
int q;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++) scanf("%d",&a[i]);
memset(c,0,sizeof(c));
scanf("%d",&q);
for(i=1;i<=q;i++)
{
scanf("%d%d",&p[i].l,&p[i].r);
p[i].id=i;
}
int pt=1;
hash.clear();
sort(p+1,p+q+1,cmp);
for(i=1;i<=q;i++)
{
while(pt<=p[i].r)
{
if(hash[a[pt]]!=0)
{
update(hash[a[pt]],-a[pt]);
}
update(pt,a[pt]);
hash[a[pt]]=pt;
pt++;
}
ans[p[i].id]=sum(p[i].r)-sum(p[i].l-1);
}
for(i=1;i<=q;i++)
{
printf("%I64d\n",ans[i]);
}
}
return 0;
}