#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn = 30005;
int n,m;
ll num[maxn],tmp[maxn];
int vis[maxn],pre[maxn];
ll tree[maxn<<2];
struct node
{
int l,r,pos;
bool operator < (const node& T) const
{
return r<T.r;
}
}val[100005];
ll ans[100005];
void update(int pos,ll c,int l,int r,int root)
{
if(l==r)
{
tree[root] = c;
return ;
}
int mid = (l+r)/2;
if(pos<=mid) update(pos,c,l,mid,root<<1);
if(pos>mid) update(pos,c,mid+1,r,root<<1|1);
tree[root] = tree[root<<1] + tree[root<<1|1];
}
ll query(int a,int b,int l,int r,int root)
{
if(a<=l&&b>=r)
return tree[root];
int mid = (l+r)/2;
ll res = 0;
if(a<=mid) res+=query(a,b,l,mid,root<<1);
if(b>mid) res += query(a,b,mid+1,r,root<<1|1);
return res;
}
int main()
{
int cases;
scanf("%d",&cases);
while(cases--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%I64d",&num[i]),tmp[i] = num[i];
scanf("%d",&m); sort(tmp,tmp+n);
for(int i=0;i<m;i++)
{
scanf("%d%d",&val[i].l,&val[i].r);
val[i].pos = i;
}
sort(val,val+m);
memset(tree,0,sizeof(tree));
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
memset(ans,0,sizeof(ans));
int j = 0;
for(int i=0;i<n;i++)
{
int t = upper_bound(tmp,tmp+n,num[i])-tmp;
//printf("s %d\n",t);
if(vis[t])
{
update(pre[t],0,1,n,1);
update(i+1,num[i],1,n,1);
pre[t] = i+1;
}
else
{
update(i+1,num[i],1,n,1);
pre[t] = i+1;
vis[t] = 1;
}
for(;j<m;j++)
{
if(i+1!=val[j].r) break;
ans[val[j].pos] = query(val[j].l,val[j].r,1,n,1);
}
}
for(int i=0;i<m;i++)
{
printf("%I64d\n",ans[i]);
}
}
return 0;
}
hdu3333(线段树离散化离线处理)
最新推荐文章于 2022-08-10 23:25:00 发布