思路:和求区间内有多少个不同的数一样,只不过改下权值。
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #define Maxn 50010 #define LL __int64 #define lowbit(x) (x&(-x)) using namespace std; int pre[1000010],num[Maxn],n; LL ans[Maxn*4],C[Maxn]; struct Query{ int i,l,r; int operator<(const Query &temp) const{ return r<temp.r; } }qt[Maxn*4]; void update(int pos,LL val) { while(pos<=n){ C[pos]+=val; pos+=lowbit(pos); } } LL Sum(int pos) { LL sum=0; while(pos){ sum+=C[pos]; pos-=lowbit(pos); } return sum; } int main() { int i,j,t,m; scanf("%d",&t); while(t--){ memset(C,0,sizeof(C)); memset(pre,0,sizeof(pre)); scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&num[i]); scanf("%d",&m); for(i=1;i<=m;i++){ scanf("%d%d",&qt[i].l,&qt[i].r); qt[i].i=i; } sort(qt+1,qt+1+m); int j=1; for(i=1;i<=n;i++){ int pos=pre[num[i]]; update(pos+1,num[i]); update(i+1,-num[i]); pre[num[i]]=i; while(qt[j].r==i&&j<=m){ ans[qt[j].i]=Sum(qt[j].l); j++; } if(j>m) break; } /* for(i=1;i<=n;i++) printf("%I64d ",Sum(i)); */ for(i=1;i<=m;i++) printf("%I64d ",ans[i]); } return 0; }