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

这个题要求区间内不同值的和,一开始没有任何思路,看了题解,原来需要对查询进行离线操作。

因为需要求区间内互异值的和,对于一个固定的区间的话,自然只需要对于相同的值只留一个,其他置零即可。

但是对于动态的查询区间,保留的那个值的位置相对关键。

通过对查询的区间进行排序可以讲区间有序的排列(以区间的右端点递增排序)。

因为这样的话,对于这个数列,从第一个逐个插入,那么区间是[1, 1]->[1, 2]->[1, 3]……这样生成的,如果我们对于a[i],把之前出现过的a[i]都置零,这样此时对于已生成的区间[1, i],我们查询区间和[k, i]的时候(因为区间是按照右端点有序查询的),必然对于任意值p,都是先包含离i最近的那个p,才会包含前面的p,而前面的p已经被置零,故不会加入计算。而离i最近的p又会加入计算,不会影响结果。

所以这样边生成区间[1, i],边对于[k, i]区间查询。对于之前出现过的a[i]置零,便可以达到查询效果。当然最好输出的结果是按照题目要求的查询顺序输出的,这里采用了保存在sum数组中。

不过这里还有一点就是,如何对于之前的a[i]置零,此处采用了map,map里保存了最右端的a[i]的脚标,这样不断更新即可。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#define LL long long using namespace std; //线段树
//区间每点增值,求区间和
const int maxn = 30005;
struct node
{
int lt, rt;
LL val;
}tree[4*maxn]; //向上更新
void PushUp(int id)
{
tree[id].val = tree[id<<1].val + tree[id<<1|1].val;
} //建立线段树
void Build(int lt, int rt, int id)
{
tree[id].lt = lt;
tree[id].rt = rt;
tree[id].val = 0;//每段的初值,根据题目要求
if (lt == rt)
{
//tree[id].val = 1;
return;
}
int mid = (lt + rt) >> 1;
Build(lt, mid, id<<1);
Build(mid+1, rt, id<<1|1);
//PushUp(id);
} //更改区间内某个点的值
void Change(int lt, int rt, int id, int to)
{
if (lt <= tree[id].lt && rt >= tree[id].rt)
{
tree[id].val = to;
return;
}
int mid = (tree[id].lt + tree[id].rt) >> 1;
if (lt <= mid)
Change(lt, rt, id<<1, to);
if (rt > mid)
Change(lt, rt, id<<1|1, to);
PushUp(id);
} //查询某段区间内的he
LL Query(int lt, int rt, int id)
{
if (lt <= tree[id].lt && rt >= tree[id].rt)
return tree[id].val;
int mid = (tree[id].lt + tree[id].rt) >> 1;
LL ans = 0;
if (lt <= mid)
ans += Query(lt, rt, id<<1);
if (rt > mid)
ans += Query(lt, rt, id<<1|1);
return ans;
} struct qq
{
int from, to;
int id;
}q[100005]; bool cmp(qq a, qq b)
{
return a.to < b.to;
} int a[30005], n, m;
LL sum[100005]; void Work()
{
Build(1, n, 1);
map<int, int> s;
int t, now = 0;
for (int i = 1; i <= n; ++i)
{
t = s[a[i]];
if (t == 0)
{
Change(i, i, 1, a[i]);
s[a[i]] = i;
}
else
{
Change(t, t, 1, 0);
Change(i, i, 1, a[i]);
s[a[i]] = i;
}
for (;now < m && q[now].to == i; now++)
{
sum[q[now].id] = Query(q[now].from, q[now].to, 1);
}
}
} void Output()
{
for (int i = 0; i < m; ++i)
printf("%I64d\n", sum[i]);
} int main()
{
//freopen("test.in", "r", stdin);
int T;
scanf("%d", &T);
for (int times = 0; times < T; ++times)
{
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
scanf("%d", &m);
for (int i = 0; i < m; ++i)
{
scanf("%d%d", &q[i].from, &q[i].to);
q[i].id = i;
}
sort(q, q+m, cmp);
Work();
Output();
}
return 0;
}

ACM学习历程——HDU3333 Turing Tree(线段树 && 离线操作)的更多相关文章

  1. ACM学习历程—HDU 5289 Assignment(线段树 || RMQ || 单调队列)

    Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered fro ...

  2. ACM学习历程—HDU 2795 Billboard(线段树)

    Description At the entrance to the university, there is a huge rectangular billboard of size h*w (h ...

  3. ACM学习历程——POJ3321 Apple Tree(搜索,线段树)

          Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will ...

  4. HDU 3333 Turing Tree 线段树+离线处理

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Othe ...

  5. ACM学习笔记:可持久化线段树

    title : 可持久化线段树 date : 2021-8-18 tags : 数据结构,ACM 可持久化线段树 可以用来解决线段树存储历史状态的问题. 我们在进行单点修改后,线段树只有logn个(一 ...

  6. HDU 3333 Turing Tree (线段树)

    Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  7. SPOJ D-query && HDU 3333 Turing Tree (线段树 && 区间不相同数个数or和 && 离线处理)

    题意 : 给出一段n个数的序列,接下来给出m个询问,询问的内容SPOJ是(L, R)这个区间内不同的数的个数,HDU是不同数的和 分析 : 一个经典的问题,思路是将所有问询区间存起来,然后按右端点排序 ...

  8. HDU3333 Turing Tree 离线树状数组

    题意:统计一段区间内不同的数的和 分析:排序查询区间,离线树状数组 #include <cstdio> #include <cmath> #include <cstrin ...

  9. HDU3333 Turing Tree(线段树)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=3333 Description After inventing Turing Tree, 3x ...

随机推荐

  1. java 开发环境安装

    一.在mac上安装jdk 1. 下载Mac版本的JDK并安装      http://www.oracle.com/technetwork/java/javase/downloads/index.ht ...

  2. centOS 7中上网以及网卡的一些设置

    在VMWare中安装LinuxOS是个非经常见的事情. 可是,关于虚拟机的上网问题.想在这里总结一下,里面还有不懂的问题.希望能够得到前辈的解惑. 一.VMWare网卡的设置的三种选项: Bridge ...

  3. python之脚本参数optparse

    import optparse usage = "myprog[ -f <filename>][-s <xyz>] arg1[,arg2..]" opter ...

  4. debian jessie install note

    Debian支持非常多的硬件,包括arm/mips/ppc/x86,于是想安装个Debian看看,也不想总屈服在canonical的ubuntu下面. 光盘镜像太多了 纯社区版的安装总是没有想像得那么 ...

  5. Android之怎样全屏显示

    三种方法: 1 自己定义主题(见设置自己定义样式和主题一节) http://blog.csdn.net/wei_chong_chong/article/details/47438907 2 使用系统自 ...

  6. HDU1864 最大报销额 01背包

    非常裸的01背包,水题.注意控制精度 #include <iostream> #include <algorithm> #include <cstdio> #inc ...

  7. python 基础 1.3 使用pycharm给python传递参数及pycharm调试模式

    一.通过pycharm 给python传递函数 1. 在pycharm终端中写入要获取的参数,进行获取 1>启动pycharm 中Terminal(终端) 窗口 点击pycharm左下角的图标, ...

  8. 1194: [HNOI2006]潘多拉的盒子

    1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 464  Solved: 221[Submit][Stat ...

  9. windowsphone8.1学习笔记之应用数据(一)

    数据存储分为两种:云存储和应用数据(即本地存储),wp中的应用数据分为两种,一种是应用设置:一种是应用文件.wp的数据相关都是通过ApplicationData来实现,一个程序只有数据存储区. 先说应 ...

  10. JavaEE与Spring

    在Java社区中,Spring与Java EE之争是个永恒的话题.在这场争论中,来自两个阵营的布道师.架构师与铁杆粉丝都在不遗余力地捍卫着本方的尊严,并试图说服对方加入到自己的阵营当中,但结果却是双方 ...