HDU 3333&&HDU-3874 Necklace 离线树状数组
2014-06-24 09:49
375 查看
这题是要求一段区间内的不重复的数字之和。我们通过对询问区间的右端点进行排序,然后记录每一数字的上一次的出现的位置,由于询问都是不回溯的那么就可以线性的更新了。
这道题的区间可能是反的,可能给出的区间前面大后面小,需要判断一下。
写树状数组时下标最好都从1开始,但是排序时不要忘了此时是n+1个元素。
#include <cstdio> #include <map> #include <algorithm> using namespace std; int N,M; int num[50050]; long long C[50050]; struct Node{ int L; int R; int id; }P[200020]; long long ans[200020]; int lowbit(int x){ return x&(-x); } long long sum(int x){ long long ret=0; while (x>0) { ret+=C[x];x-=lowbit(x); } return ret; } int add(int x,long long d){ while (x<=N){ C[x]+=d;x+=lowbit(x); } return 0; } long long query(int L,int R){ return sum(R)-sum(L-1); } int cmp(Node a,Node b){ return a.R<b.R; } int main (){ int T;scanf("%d",&T); while (T--){ map <int ,int > vis; vis.clear(); scanf("%d",&N); for (int i=0;i<N;i++) scanf("%d",&num[i]),C[i]=0; C =0; scanf("%d",&M); for (int i=0;i<M;i++){ scanf("%d%d",&P[i].L,&P[i].R),P[i].id=i; if (P[i].L>P[i].R){ int c=P[i].R; P[i].R=P[i].L; P[i].L=c; } } sort(P,P+M,cmp); int j=0; for (int i=0;i<M;i++){ while (j<N&&j+1<=P[i].R){ if (vis[num[j]]!=0) { add(vis[num[j]],-num[j]); vis[num[j]]=j+1; add(vis[num[j]],num[j]); } else { vis[num[j]]=j+1; add(vis[num[j]],num[j]); } j++; } ans[P[i].id]=query(P[i].L,P[i].R); } for (int i=0;i<M;i++){ printf("%I64d\n",ans[i]); } } return 0; }就这道题卡了我三次T_T 读题必须要认真啊
这道题的区间可能是反的,可能给出的区间前面大后面小,需要判断一下。
写树状数组时下标最好都从1开始,但是排序时不要忘了此时是n+1个元素。
相关文章推荐
- HDU 3874 Necklace (树状数组 | 线段树 的离线处理)
- HDU 3874 Necklace(树状数组的离线操作)
- hdu 3874 Necklace 树状数组 离线操作
- HDU 3874 Necklace(树状数组离线处理)
- HDU 3874 Necklace(树状数组离线处理)
- HDU 3874 Necklace 离线+树状数组
- HDU 3874 Necklace(树状数组的离线操作)
- HDU 3874 Necklace 树状数组 + 离线处理
- HDU(3874)树状数组+离线
- HDU 3874 Necklace 树状数组的应用
- hdu 3874 树状数组 离线处理
- hdu 3874 Necklace (树状数组)
- HDU 3874 Necklace (树状数组)
- hdu-3874-Necklace-(树状数组)
- hdu 3874 Necklace(树状数组的灵活应用)
- HDU 3874 树状数组 + 离线处理
- hdu 1166 树状数组 & 线段树
- hdu 3874 树状数组
- HDU 3333 & 3874 (线段树+离线询问)
- hdu 3874 Necklace 求数组任意区间和(相同元素只算一次) 树状数组+离线算法