HDU--3333

xiaoxiao2021-02-28  70

题意就是让你求给定数的区间和,数值相同只加一次

题目链接:HDU-3333

主要就是区间右端点排序和这句话“对于要查询的区间,它的右端点固定后,那么重复的数字便是右面开始最后一次出现的

AC代码:

#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<map> using namespace std; #define MM(x,y) memset(x,y,sizeof(x)) const int N=1e5+10; typedef long long ll; struct Node { int l,r,pos; bool operator < (const Node &cmp) const { return r<cmp.r; } }; struct Node q[N]; ll ans[N],bit[N]; int a[N]; map<int,int>mp; void add(int k,ll num) { while(k<=N) { bit[k]+=num; k+=k&-k; } } ll sum(int k) { ll res=0; while(k>0) { res+=bit[k]; k-=k&-k; } return res; } int main() { int tcase,n,m,i,j; scanf("%d",&tcase); while(tcase--) { mp.clear(); MM(a,0); MM(ans,0); MM(bit,0); MM(q,0); scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&a[i]); } scanf("%d",&m); for(i=1;i<=m;i++) { scanf("%d %d",&q[i].l,&q[i].r); q[i].pos=i; } sort(q+1,q+m+1); int index=1; for(i=1;i<=n;i++) { if(mp.find(a[i])!=mp.end()) { add(mp[a[i]],(ll)-a[i]); } mp[a[i]]=i; add(i,a[i]); while(q[index].r==i&&index<=m) { ans[q[index].pos]=sum(q[index].r)-sum(q[index].l-1); ++index; } } for(i=1;i<=m;i++) { printf("%lld\n",ans[i]); } } return 0; }

转载请注明原文地址: https://www.6miu.com/read-56367.html

最新回复(0)