【HDU 3333】【离线询问 树状数组 前驱思想】Turing Tree【 求区间中不同的数的和】
2016-10-03 17:04
477 查看
传送门:HDU 3333 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;
}
描述:
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;
}
相关文章推荐
- 【codeforces 703 D】【离线询问 树状数组 前驱思想 前缀异或和】D. Mishka and Interesting sum【 区间内出现次数偶数的数的异或和】
- 【Codeforces Round 365 (Div 2)D】【离线询问 树状数组 前驱思想】Mishka and Interesting sum 区间内出现次数偶数的数的异或和
- HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数
- HDU 3333 Turing Tree 树状数组 离线查询
- 【HDU5654 BestCoder Round 77 (div1) D】【前驱位置思想 排序 树状数组】xiaoxin and his watermelon candy 区间内多少个不同连续单升三元
- HDU 3333 Turing Tree(树状数组离线处理)
- hdu 3333 Turing Tree(树状数组离线操作)
- hdu 3333 Turing Tree(线段树求区间内不同值之和+离线处理)
- HDU 3333 Turing Tree (离线树状数组)
- hdu 3333 Turing Tree 线段树 离线查询(区间内不同的数之和)
- HDU 3333 Turing Tree (树状数组)
- [区间GCD预处理 树状数组 离线] HDU 5869 Different GCD Subarray Query
- hdu-3333-Turing Tree(树状数组)
- SPOJ DQUERY(树状数组离线处理 or 主席树 区间不同数个数)
- HDU 3333 Turing Tree (离线询问+线段树)
- BZOJ 题目1878: [SDOI2009]HH的项链(树状数组离线求区间不同种类数)
- SPOJ D-query && HDU 3333 Turing Tree (线段树 && 区间不相同数个数or和 && 离线处理)
- hdu 3333(树状数组,离线,离散化)
- HDU - 3333 Turing Tree(树状数组)
- HDU 4638 多校第四场1007 离线询问,树状数组||线段树维护