HDU 3333 Turing Tree (线段树)
Turing Tree
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4768 Accepted Submission(s): 1686
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.
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).
2
3
1 1 4
2
1 2
2 3
5
1 1 2 1 3
3
1 5
2 4
3 5
1
5
6
3
6询问任意区间里有多少个不相同的数字,首先要想到,判断某个数字是否出现区间里,肯定是看的它的位置是否在区间内,那么重复的数字怎么办呢,我们只要记录这个数字最后一个位置就好了,因为这个数字是否出现在区间里,通过它最后一个出现的位置,完全可以决定。遇到这种10万个询问区间的问题,如果题目不是强制要求在线,我们应该考虑离线做,这样会简单很多把区间按照右端点排序,也可以按照左端点,然后逐个将数字插入线段树中,遇到右端点就开始查询查询这个区间的和,点更新的时候,如果之前出现过,先删除,再更新位置。这些操作,都可以用线段树解决#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <map> using namespace std;
typedef long long int LL;
const int maxn=3*1e4;
LL num[maxn*4+5];
LL a[maxn+5];
LL aa[maxn+5];
int cot;
LL c[maxn+5];
map<LL,int> m;
int st[maxn+5];
struct Node
{
int l,r;
int tag;
LL ans; }b[100005];
int n;
void pushup(int node)
{
num[node]=num[node<<1]+num[node<<1|1];
}
void update(int node,int l,int r,int val,LL tag)
{
if(l==r)
{
num[node]=tag;
return;
}
int mid=(l+r)>>1;
if(val<=mid) update(node<<1,l,mid,val,tag);
else update(node<<1|1,mid+1,r,val,tag);
pushup(node);
}
LL query(int node,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
return num[node];
int mid=(l+r)>>1;
LL ret=0;
if(L<=mid) ret+=query(node<<1,l,mid,L,R);
if(R>mid) ret+=query(node<<1|1,mid+1,r,L,R);
return ret;
}
int cmp(Node a,Node b)
{
if(a.r==b.r)
return a.l<b.l;
return a.r<b.r;
}
int cmp2(Node a,Node b)
{
return a.tag<b.tag;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(num,0,sizeof(num));
m.clear();
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
c[i]=a[i];
}
sort(a+1,a+n+1);
int pos=0;
for(int i=1;i<=n;i++)
if(!m[a[i]]) m[a[i]]=++pos;
int q;
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d",&b[i].l,&b[i].r);
b[i].tag=i;
}
sort(b+1,b+1+q,cmp);
int k=1;
memset(st,0,sizeof(st));
for(int i=1;i<=n;i++)
{
if(st[m[c[i]]])
update(1,1,n,st[m[c[i]]],0);
st[m[c[i]]]=i; update(1,1,n,i,c[i]);
while(i==b[k].r&&k<=q)
{
b[k].ans=query(1,1,n,b[k].l,b[k].r);
k++;
}
}
sort(b+1,b+q+1,cmp2);
for(int i=1;i<=q;i++)
printf("%lld\n",b[i].ans);
}
return 0;
}
HDU 3333 Turing Tree (线段树)的更多相关文章
- HDU 3333 Turing Tree 线段树+离线处理
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Othe ...
- SPOJ D-query && HDU 3333 Turing Tree (线段树 && 区间不相同数个数or和 && 离线处理)
题意 : 给出一段n个数的序列,接下来给出m个询问,询问的内容SPOJ是(L, R)这个区间内不同的数的个数,HDU是不同数的和 分析 : 一个经典的问题,思路是将所有问询区间存起来,然后按右端点排序 ...
- HDU 3333 Turing Tree(树状数组/主席树)
题意 给定一个长度为 \(n\) 的序列,\(m\) 个查询,每次查询区间 \([L,R]\) 范围内不同元素的和. \(1\leq T \leq 10\) \(1 \leq n\leq 300 ...
- HDU 3333 Turing Tree (主席树)
题意:给定上一个序列,然后有一些询问,求区间 l - r 中有多少个不同的数的和. 析:和求区间不同数的方法是一样,只要用主席树维护就好. 代码如下: #pragma comment(linker, ...
- hdu 3333 Turing Tree 图灵树(线段树 + 二分离散)
http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Others) ...
- hdu 3333 Turing Tree(线段树+离散化)
刚看到是3xian大牛的题就让我菊花一紧,觉着这题肯定各种高端大气上档次,结果果然没让我失望. 刚开始我以为是一个普通的线段树区间求和,然后啪啪啪代码敲完测试没通过,才注意到这个求和是要去掉相同的值的 ...
- HDU 3333 Turing Tree 离线 线段树/树状数组 区间求和单点修改
题意: 给一个数列,一些询问,问你$[l,r]$之间不同的数字之和 题解: 11年多校的题,现在属于"人尽皆知傻逼题" 核心思想在于: 对于一个询问$[x,R]$ 无论$x$是什么 ...
- HDU 3333 Turing Tree(离线树状数组)
Turing Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)
题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...
随机推荐
- 安装配置PhoneGap开发环境(二)——使用Cordova取代PhoneGap创建项目
1 Cordova是谁 PhoneGap的官方文档说的非常清楚.Cordova是PhoneGap的引擎,这两者的关系类似于WebKit与Chrome浏览器的关系.所以一些核心的基础操作对于Cordov ...
- Python目录常用操作
os.path.basename(path) #取文件名 os.path.getsize(path) #取文件大小 os.path.exists(path) #文件是否存在 os.path.dirna ...
- THREADSPOOL
STPStartInfo stp = new STPStartInfo();//线程详细配置参数 stp.CallToPostExecute = CallToPostExecute.Always;// ...
- python内置函数之dict()
class dict(**kwargs) 返回一个字典.本方法用来创建一个字典对象.只能传入一个参数. >>> dict(a=1) {'a': 1} 也可以传入映射函数作为参数 &g ...
- jquery 对table的一些操作 怎么获取tr下的第二个td元素?
1.HTML结构 <table id = "test"> <tr><td>1</td><td>1</td>& ...
- Web 服务器被配置为不列出此目录的内容
在Web.configue文件里,会多出来部分代码,应该是允许浏览目录: <?xml version="1.0" encoding="utf-8"?> ...
- 解决select菜单边框无法设置的问题
<span style="border:1px solid green; position:absolute; overflow:hidden"><select ...
- lua工具库penlight--08额外的库(一)
额外的库 在这一节中的库不再被认为是Penlight的核心部分,但在需要时,仍提供专门的功能. 简单的输入的模式 Lua 的字符串模式匹配是非常强大,通常您将不需要传统的正则表达式库.即便如此,有时 ...
- (转)love2d有用的辅助库--gamework
此文转自朱大仙,感谢他的劳作. 翻译来源地址:https://github.com/Kadoba/gamework gamework是控制LOVE2D游戏进程流的一个项目. ↑ 这个是按原文译的, 当 ...
- SenCha Touch 与 EXTJS 安装Myeclipse 插件
http://www.cnblogs.com/jirimutu01/default.html 关于SenchaEclipsePlugin插件的安装和使用 使用过eclipse开发java程序的人都知道 ...