hdu 3333(树状数组,离线,离散化)
2016-08-05 13:28
513 查看
Total Submission(s): 4455 Accepted Submission(s): 1561
[align=left]Problem Description[/align]
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.
[align=left]Input[/align]
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).
[align=left]Output[/align]
For each Query, print the sum of distinct values of the specified subsequence in one line.
[align=left]Sample Input[/align]
2
3
1 1 4
2
1 2
2 3
5
1 1 2 1 3
3
1 5
2 4
3 5
[align=left]Sample Output[/align]
1
5
6
3
6
[align=left]Author[/align]
3xian@GDUT
好像看过出题人的博客 2333333
题意:求出给定区间内不同种类的数的和值。
题解:
求区间啥啥的 八九不离十是线段树,树状数组,这题我们选用树状数组。
为了让区间和能表示我们想要的结果,同一个数只能出现一次,如果再次出现,我们需要把之前出现的删掉,再在当前位置加入。
则这样操作后,保证了当前位置前的区间是处理完的,是符合题意得。所以我们不能按照题给的顺序求区间,此时想到离线操作,我们把每个区间的右端点升序排列(此时操作里还需要一步离散化,因为最后需要按照给定区间的顺序进行输出)每加入数ai,就判断ai前有没有一个完整的区间,如果有,求出这个区间的ans。剩下操作如上面所说。
Turing Tree
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4455 Accepted Submission(s): 1561
[align=left]Problem Description[/align]
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.
[align=left]Input[/align]
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).
[align=left]Output[/align]
For each Query, print the sum of distinct values of the specified subsequence in one line.
[align=left]Sample Input[/align]
2
3
1 1 4
2
1 2
2 3
5
1 1 2 1 3
3
1 5
2 4
3 5
[align=left]Sample Output[/align]
1
5
6
3
6
[align=left]Author[/align]
3xian@GDUT
好像看过出题人的博客 2333333
题意:求出给定区间内不同种类的数的和值。
题解:
求区间啥啥的 八九不离十是线段树,树状数组,这题我们选用树状数组。
为了让区间和能表示我们想要的结果,同一个数只能出现一次,如果再次出现,我们需要把之前出现的删掉,再在当前位置加入。
则这样操作后,保证了当前位置前的区间是处理完的,是符合题意得。所以我们不能按照题给的顺序求区间,此时想到离线操作,我们把每个区间的右端点升序排列(此时操作里还需要一步离散化,因为最后需要按照给定区间的顺序进行输出)每加入数ai,就判断ai前有没有一个完整的区间,如果有,求出这个区间的ans。剩下操作如上面所说。
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <cmath> #include <queue> #include <set> #include <map> #include <vector> #include <stack> #include <algorithm> #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define mem(a) memset(a, 0, sizeof(a)) #define eps 1e-5 #define M 100005 #define N 30010 #define INF 0x3f3f3f3f #define ll long long using namespace std; map<int,int> mp; int t,n,m; ll rre[M]; ll f ; int a ; struct node { int l,r,id; bool operator<(const node &n)const{ return r<n.r||(r==n.r&&l<n.l); } }qu[M]; int lowbit(int x) { return x&(-x); } void add(int x,int y) { while(x<=n) { f[x]+=y; x+=lowbit(x); } } ll sum(int x) { ll ans=0; while(x>0) { ans+=f[x]; x-=lowbit(x); } return ans; } int main() { scanf("%d",&t); while(t--) { scanf("%d",&n); mem(f); for(int i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&m); for(int i=0;i<m;i++) { int x,y; scanf("%d%d",&x,&y); qu[i]=(node){x,y,i}; } sort(qu,qu+m); int cur=0; mp.clear(); for(int i=1;i<=n;i++) { if(mp.find(a[i])==mp.end())//之前没加入过a[i]这个数。 { add(i,a[i]); mp.insert(make_pair(a[i],i));//记录a[I]出现的位置。 } else { add(i,a[i]); add(mp[a[i]],-a[i]); mp[a[i]]=i; } while(qu[cur].r==i)//判断之前有没有完整区间 { rre[qu[cur].id]=sum(qu[cur].r)-sum(qu[cur].l-1); cur++; } } for(int i=0;i<m;i++) cout<<rre[i]<<endl; } return 0; }
相关文章推荐
- 【HDU 3333】【离线询问 树状数组 前驱思想】Turing Tree【 求区间中不同的数的和】
- HDU 3333 Turing Tree (离线树状数组)
- HDU 3333 | Codeforces 703D 树状数组、离散化
- HDU 3333 Turing Tree 树状数组 离线查询
- hdu 3333(树状数组 + 离线操作)
- HDU-3333-Turing Tree-(树状数组,离散化)
- HDU 3333 Turing Tree(树状数组离线处理)
- HDU 4417 —— Super Mario(树状数组,离散化,离线处理)
- hdu 3333 Turing Tree(树状数组离线操作)
- HDU(3333)树状数组+离线
- 树状数组,离散化,突破口(Segment Game,HDU 5372)
- hdu 4368 树状数组 离线维护
- hdu 5489 Removed Interval 2015合肥网络赛 树状数组 dp 离散化/dp
- HDU - 5792 树状数组 + 离散化
- hdu 4417 离线树状数组
- HDU - 3333 Turing Tree(树状数组)
- HDU-5877-Weak Pair【树状数组】【离散化】【DFS】【2016大连网络】【好题】
- hdu 4630 No Pain No Game(树状数组离线操作)
- hdu-4630-No Pain No Game-(树状数组,离线处理)
- 树状数组+离散化(hdu 5862)