您的位置:首页 > 其它

【HDU 3333】【离线询问 树状数组 前驱思想】Turing Tree【 求区间中不同的数的和】

2016-10-03 17:04 477 查看
传送门:HDU 3333 Turing Tree

描述:


Turing Tree

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 4736    Accepted Submission(s): 1674


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.

 

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).

 

Output

For each Query, print the sum of distinct values of the specified subsequence in one line.

 

Sample Input

2
3
1 1 4
2
1 2
2 3
5
1 1 2 1 3
3
1 5
2 4
3 5

 

Sample Output

1
5
6
3
6

 

Author

3xian@GDUT

 

Source

HDOJ Monthly Contest – 2010.03.06

 

Recommend

lcy   |   We have carefully selected several similar problems for you:  1542 3397 1540 1255 1828 

 
题意:

求区间中不同的数的和

思路:

离线的方法,对所有的询问按照右端点排序,然后对于每个数只保留最后一个(因为每个数只保留最后一个,所以只需对右端点排序就好了),用树状数组来单点更新,查询一下就行了。

建议用一些样例模拟一下代码中的过程

复杂度:
O(mlongn)

代码:
#include <bits/stdc++.h>
#define pr(x) cout << #x << "= " << x << " " ;
#define pl(x) cout << #x << "= " << x << endl;
#define mst(ss,b) memset(ss,b,sizeof(ss));
#define ll __int64
using namespace std;

template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
const int N=3e4+10;
const int M=1e5+10;
struct node{
int l,r,id;
bool operator < (const node& tmp) const {
return r<tmp.r;
}
}q[M];
ll ans[M],a
;
map<ll, int>vis;
int pre[M];
ll bit
;
int n,m;

void update(int i,int x){
while(i<=n){
bit[i]+=x;
i+=i&-i;
}
}

ll query(int i){
ll s=0;
while(i>0){
s+=bit[i];
i-=i&-i;
}
return s;
}

int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int t;
read(t);
while(t--){
read(n);
mst(pre, 0); mst(bit, 0); vis.clear();
for(int i=1; i<=n; i++){
read(a[i]);
pre[i]=vis[a[i]];//前驱
vis[a[i]]=i;
}
read(m);
for(int i=1; i<=m; i++){
read(q[i].l);read(q[i].r);
q[i].id=i;
}
sort(q+1, q+m+1);
for(int i=1,r=1; i<=m; i++){
while(r<=q[i].r){
if(pre[r])
update(pre[r], -a[r]);//删除前驱
update(r, a[r]);//添加最右边的数
r++;
}
ans[q[i].id]=query(q[i].r)-query(q[i].l-1);
}
for(int i=1; i<=m; i++)printf("%I64d\n", ans[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐