博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU3333 Turing Tree 树状数组+离线处理
阅读量:4338 次
发布时间:2019-06-07

本文共 2218 字,大约阅读时间需要 7 分钟。

Turing Tree

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

Total Submission(s): 4948    Accepted Submission(s): 1746

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
 
 
题意:给T组数据,每组数据n个数及m个询问,每个询问[l,r]问区间不同的数的和为多少?
 
题解:每个询问离线处理,先按r递增排,再按l递增排序,定义一个last[]用于记录数最后出现的位置,维护一个已经更新的区间[ll,rr],每次只要加入[ll,l],[rr,r]的区间,放入树状数组进行求和
注意:加入树状数组的时候要判断last[],如果出现过就要删除原来的,保证树状数组里每个数只出现一次而且在最后一个位置
每个询问答案是sum[rr]-sum[ll-1]
 
#include
#define N 145000#define mes(x) memset(x, 0, sizeof(x));#define ll __int64const long long mod = 1e9+7;const int MAX = 0x7ffffff;using namespace std;ll c[N], n, a[N];ll ans[N];map
last;struct node{ int l,r,k;}q[N];int lowbit(int x){ return x&(-x);}int cmp(node a, node b){ if(a.r == b.r) return a.l
0){ sum = sum+c[x]; x -= lowbit(x); } return sum;}void add(int x,int d){ while(x <= n){ c[x] = c[x]+d; x += lowbit(x); }}int main(){ int T, i, j, m, l, r; while(~scanf("%d", &T)){ while(T--){ scanf("%d", &n); for(i=1;i<=n;i++) scanf("%d", &a[i]); scanf("%d", &m); for(i=0;i

 

 
 

 

 

转载于:https://www.cnblogs.com/Noevon/p/6144021.html

你可能感兴趣的文章
深入理解Java虚拟机&运行时数据区
查看>>
02-环境搭建
查看>>
spring第二冲刺阶段第七天
查看>>
搜索框键盘抬起事件2
查看>>
阿里百川SDK初始化失败 错误码是203
查看>>
透析Java本质-谁创建了对象,this是什么
查看>>
BFS和DFS的java实现
查看>>
关于jquery中prev()和next()的用法
查看>>
一、 kettle开发、上线常见问题以及防错规范步骤
查看>>
eclipse没有server选项
查看>>
CRC码计算及校验原理的最通俗诠释
查看>>
使用Gitbook来编写你的Api文档
查看>>
jquery扩展 $.fn
查看>>
Markdown指南
查看>>
influxDB的安装和简单使用
查看>>
JPA框架学习
查看>>
JPA、JTA、XA相关索引
查看>>
机器分配
查看>>
php opcode缓存
查看>>
springcloud之Feign、ribbon设置超时时间和重试机制的总结
查看>>