hdu3333(hash+树状数组)
来源:互联网 发布:阿里云免费半年 编辑:程序博客网 时间:2024/05/29 15:23
Turing Tree
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2578 Accepted Submission(s): 878
Problem Description
After inventing Turing Tree, 3xian always felt boring when solving problems about intervals, because Turing Tree could easily have the solution. As well, wily 3xian made lots of new problems about intervals. So, today, this sick thing happens again...
Now given a sequence of N numbers A1, A2, ..., AN and a number of Queries(i, j) (1≤i≤j≤N). For each Query(i, j), you are to caculate the sum of distinct values in the subsequence Ai, Ai+1, ..., Aj.
Now given a sequence of N numbers A1, A2, ..., AN and a number of Queries(i, j) (1≤i≤j≤N). For each Query(i, j), you are to caculate the sum of distinct values in the subsequence Ai, Ai+1, ..., Aj.
Input
The first line is an integer T (1 ≤ T ≤ 10), indecating the number of testcases below.
For each case, the input format will be like this:
* Line 1: N (1 ≤ N ≤ 30,000).
* Line 2: N integers A1, A2, ..., AN (0 ≤ Ai ≤ 1,000,000,000).
* Line 3: Q (1 ≤ Q ≤ 100,000), the number of Queries.
* Next Q lines: each line contains 2 integers i, j representing a Query (1 ≤ i ≤ j ≤ N).
For each case, the input format will be like this:
* Line 1: N (1 ≤ N ≤ 30,000).
* Line 2: N integers A1, A2, ..., AN (0 ≤ Ai ≤ 1,000,000,000).
* Line 3: Q (1 ≤ Q ≤ 100,000), the number of Queries.
* Next Q lines: each line contains 2 integers i, j representing a Query (1 ≤ i ≤ j ≤ N).
Output
For each Query, print the sum of distinct values of the specified subsequence in one line.
Sample Input
231 1 421 22 351 1 2 1 331 52 43 5
Sample Output
15636本题要求给定区间内不相同数的和,由于频繁地进行查询操作求区间很大,应用线段树,由于是求和操作,可以用树状数组代替线段树,在时间复杂度相同的情况下,树状数组比线段树编程简单,时间常数要小。此题的重点不在这,关键在于处理不相同的数,很容易联想到hash,但看题目的数据0 ≤ Ai ≤ 1,000,000,000,开辟如此大的数组可能会超内存,即不能直接hash又由于数据的个数1 ≤ N ≤ 30,000不大,可以考虑在此上做文章,即将数据离散化处理,将数据映射到一个新的数组,新数组存放不同数据的值,从而相同数据有着相同的下标,再通过下标构建hash表,hash数组开30,000,不会超内存。为了解决这道题,在查询时必须删除重复元素,可以在来一个数Ai时,首先将其插在当前位置,再通过hash判断该数有无在此之前出现,若出现则通过hash表里的下表值找到并在之前出现位置删除该数。为了保证每次查询区间【a,b】内无重复数字,可以将查询区间存储起来,然后按右端点升序排列。在一个个将Ai插入树状数组,当元素下表i等于某个查询区间有端点时,计算该查询区间的和,由于排除了左边的重复元素,所以答案是正确的。#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int MAX=30000+10;struct node{int s,e,ind;__int64 sum;}qu[100000+10];//s,e,ind分别表示区间端点和该询问的下标__int64 da[MAX];__int64 ta[MAX];__int64 C[MAX];int Lowbit[MAX];int visited[MAX];int cnt;bool cmp1(node a,node b){return a.e<b.e;}bool cmp2(node a,node b){return a.ind<b.ind;}__int64 QuerySum(int p)//查询原数组中下标1-p的元素的和 { __int64 nSum = 0; while( p > 0 ) { nSum += C[p]; p -= Lowbit[p]; } return nSum; } void Modify( int p,__int64 val) //原数组中下表为p的元素+val,导致C[]数组中部分元素值的改变{ while( p <= MAX ) { C[p] += val; p+=Lowbit[p]; } } int Binary_find(__int64 w){int l=1,r=cnt-1,mid;while(l<=r){mid=(l+r)>>1;if(ta[mid]<w)l=mid+1;else if(ta[mid]>w)r=mid-1;else {return mid;}}return 1;}int main(){int i,cas,n,q;for(i=1;i<=MAX;i++)Lowbit[i]=i&(-i);cin>>cas;while(cas--){scanf("%d",&n);for(i=1;i<=n;i++){scanf("%I64d",&da[i]);ta[i]=da[i];}cnt=1;sort(ta+1,ta+n+1);for(i=1;i<=n;i++){if(i==1||ta[i-1]!=ta[i])ta[cnt++]=ta[i];}scanf("%d",&q);for(i=1;i<=q;i++){scanf("%d%d",&qu[i].s,&qu[i].e);qu[i].ind=i,qu[i].sum=0;}sort(qu+1,qu+q+1,cmp1);memset(C,0,sizeof(C));memset(visited,0,sizeof(visited));int in,k=1;for(i=1;i<=n;i++){Modify(i,da[i]);in=Binary_find(da[i]);if(visited[in])Modify(visited[in],-da[i]);visited[in]=i;while(k<=q&&qu[k].e==i){qu[k].sum=QuerySum(qu[k].e)-QuerySum(qu[k].s-1);k++;}}sort(qu+1,qu+q+1,cmp2);for(i=1;i<=q;i++)printf("%I64d\n",qu[i].sum);}return 0;}
- hdu3333(hash+树状数组)
- HDU3333(线段树/数状数组 + hash)
- HDU3333 离线离散化树状数组
- HDU3333
- POJ2299 Ultra-QuickSort 【树状数组】+【hash】
- ural 1989(树状数组+多项式hash)
- ACdream 1019 Palindrome 树状数组+Hash
- Acdream 1019 Palindrome 树状数组 + 字符串hash
- HDU 4456 Crowd (二维树状数组 + HASH)
- bzoj 2124 神奇的树状数组+hash
- BZOJ 2124 树状数组+Hash 解题报告
- ACdreamoj 1011(树状数组维护字符串hash前缀和)
- BZOJ 3790 神奇项链 Hash+二分+树状数组
- bzoj 2124: 等差子序列 树状数组&hash
- BZOJ 2124 等差子序列 (树状数组 hash)
- bzoj2124 等差子序列 (树状数组 维护hash值)
- [BZOJ]2124 等差子序列 Hash&树状数组
- BZOJ 2124: 等差子序列 [树状数组][hash]
- 多个场景自动切换时第二个定时器无作用
- Android基础——使用Fragment适应不同屏幕和分辨率
- (1)Linux入门学习笔记
- ZOJ 3687 The Review Plan I 解题报告
- 连分数
- hdu3333(hash+树状数组)
- Ubuntu 12.10 下安装配置 JDK 7
- Kruskal算法(克鲁斯卡尔算法)---求加权连通图的最小生成树的算法
- 数学基础题
- initComponent还是constructor
- 一个高效的内存池实现
- 链表知识
- ZOJ 3689 Digging 解题报告
- XE4 F1026 File not found: JPEG.dcu Vcl name space