HDU3874树状数组的应用

来源:互联网 发布:c语言程序停止 编辑:程序博客网 时间:2024/06/05 08:06

这题的意思是求区间的和,如果不考虑重复的情况,用树状数组分分钟解决,但是不能求重复的,奈何智商低啊!参考了一下人家的代码。

用map记录当前值是否出现过,并记录这个值的最后一处的位置,当遍历到某个值时,如果前面已经出现过,那么将前面那个数的值清为0,即将map记录的这个数的位置上的数减去这个数,当前位置插入这个值。离线处理询问即可。

 

#include<bits/stdc++.h>using namespace std;#define maxn 50010typedef long long LL;int A[maxn],N;LL C[maxn*4],ans[maxn*4];struct node{int i,l,r;}q[maxn*4];map<int,int>hasn;int lowbit(int x){return x&(-x);}LL sum(int x){LL ret=0;while(x>0){ret+=(LL)C[x];x-=lowbit(x);}return ret;}void add(int x,int d){while(x<=N){C[x]+=d;x+=lowbit(x);}}int cmp(node a,node b){return a.r<b.r;}int main(){int T,M;scanf("%d",&T);while(T--){scanf("%d",&N);for(int i=1;i<=N;i++)scanf("%d",&A[i]);scanf("%d",&M);for(int i=0;i<M;i++){ scanf("%d%d",&q[i].l,&q[i].r); if(q[i].l>q[i].r)swap(q[i].l,q[i].r);q[i].i=i;}sort(q,q+M,cmp);hasn.clear();int r=1;memset(C,0,sizeof(C));for(int i=0;i<M;i++){while(r<=q[i].r){if(hasn[A[r]]!=0)add(hasn[A[r]],-A[r]);hasn[A[r]]=r;add(hasn[A[r]],A[r]);r++;}ans[q[i].i]=sum(q[i].r)-sum(q[i].l-1);}for(int i=0;i<M;i++) printf("%I64dn",ans[i]);}return 0;}

 

0 0