HDU-3333 Turning Tree

题目大意:先给出n个数字。面对q个询问区间,输出这个区间不同数的和。

题解:这道题有几种解法。这里讲一下用分块解决的方法。( 离线树状数组解法看这里 Hdu-3333 Turning Tree (离线树状数组/线段树)~~~)

以(a[i]上一次出现的位置last, a[i])数字对作为基本元素做分块。那么容易想到对于每一个询问(l,r),如果该元素的last<l那么这个元素就应该加入到ans中。  那么我们对于每一个分块,以last作为关键字排序。对于每一次询问。左右两端的分块就枚举last<l的a[i]加入到ans中,中间的分块因为排序的原因,last是有序的。那么中间的分块直接二分询问的左端点l,该分块左端点到二分得到的点都是符合条件的。

AC代码如下,因为用结构体做分块的原因。代码写得稀烂~~~。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
const int N=+;
const int SqrtN=;
struct data{
int last,v;
}a[N],b[N];
long long sum[N];
int L[SqrtN],R[SqrtN];
int pos[N];
int n,m,t; bool cmp1(data x1,data x2) { return x1.last<x2.last; } map<int,int> lst;
void init() {
lst.clear();
for (int i=;i<=n;i++) {
a[i].last=lst[a[i].v];
lst[a[i].v]=i;
}
for (int i=;i<=n;i++) b[i]=a[i]; t=sqrt(n);
for (int i=;i<=t;i++) {
L[i]=(i-)*t+;
R[i]=i*t;
}
if (R[t]<n) t++,L[t]=R[t-]+,R[t]=n; for (int i=;i<=t;i++) sort(a+L[i],a+R[i]+,cmp1); for (int i=;i<=t;i++) {
for (int j=L[i];j<=R[i];j++) {
pos[j]=i;
if (j==L[i]) sum[j]=a[j].v; else sum[j]=sum[j-]+a[j].v;
}
}
} struct cmp2
{
bool operator () (const data &a,const data &b) const {
return a.last < b.last;
}
}; long long query(int l,int r) {
int p=pos[l],q=pos[r];
long long ans=;
if (p==q) {
for (int i=l;i<=r;i++)
if (b[i].last<l) ans+=b[i].v;
} else {
for (int i=l;i<=R[p];i++) if (b[i].last<l) ans+=b[i].v;
for (int i=L[q];i<=r;i++) if (b[i].last<l) ans+=b[i].v;
for (int i=p+;i<=q-;i++) {
data temp;
temp.last=l; temp.v=-;
int x=lower_bound(a+L[i],a+R[i]+,temp,cmp2())-a;
if (x!=L[i]) ans+=sum[x-];
}
}
return ans;
} int main()
{
int T;
scanf("%d",&T);
while (T--) {
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&a[i].v);
init();
scanf("%d",&m);
for (int i=;i<=m;i++) {
int l,r;
scanf("%d%d",&l,&r);
printf("%lld\n",query(l,r));
}
}
return ;
}

HDU-3333 Turing Tree 分块求区间不同数和的更多相关文章

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

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

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

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

  3. hdu 3333 Turing Tree 图灵树(线段树 + 二分离散)

    http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Others)    ...

  4. HDU 3333 Turing Tree (主席树)

    题意:给定上一个序列,然后有一些询问,求区间 l - r 中有多少个不同的数的和. 析:和求区间不同数的方法是一样,只要用主席树维护就好. 代码如下: #pragma comment(linker, ...

  5. HDU 3333 Turing Tree(离线树状数组)

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

  6. HDU 3333 Turing Tree (线段树)

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

  7. HDU 3333 Turing Tree 离线 线段树/树状数组 区间求和单点修改

    题意: 给一个数列,一些询问,问你$[l,r]$之间不同的数字之和 题解: 11年多校的题,现在属于"人尽皆知傻逼题" 核心思想在于: 对于一个询问$[x,R]$ 无论$x$是什么 ...

  8. HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)

    题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...

  9. HDU 3333 Turing Tree (树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3333 题意就是询问区间不同数字的和. 比较经典的树状数组应用. //#pragma comment(l ...

随机推荐

  1. Android kotlin静态属性、静态方法

    只需要用 companion object 包裹相应代码块即可.以静态属性为例: class Constants { companion object { val BASE_URL = "h ...

  2. MongoDB 存储引擎选择

    MongoDB存储引擎选择 MongoDB存储引擎构架 插件式存储引擎, MongoDB 3.0引入了插件式存储引擎API,为第三方的存储引擎厂商加入MongoDB提供了方便,这一变化无疑参考了MyS ...

  3. 【leetcode】433. Minimum Genetic Mutation

    题目如下: 解题思路:我的思路很简单,就是利用BFS方法搜索,找到最小值. 代码如下: class Solution(object): def canMutation(self, w, d, c, q ...

  4. java中对象转json,json转list,json转map

    在IDEA中的springboot项目里写的一个测试例子,新建User类,四个字段,Long id , String password,String userName,int age; 以及带参构造, ...

  5. delphi 一个关于xml文件导入数据库的问题

    function LoadXml(shortPath:string;var xmlobj: IXMLDOMDocument):boolean; var tmpXml:IXMLDOMDOCUMENT; ...

  6. jdk8的stream流式计算的操作

    jdk8之后增加了流式计算,现在根据学习了流式计算,并把过程记录下来: Person.java的bean package com.zhang.collectordemo; /** * @program ...

  7. python中常犯错误之字符串列表下标问题

    下标用得是中括号[] 不是小括号() 1,python中的小括号( ):代表tuple元组数据类型,元组是一种不可变序列.创建方法很简单,大多时候都是用小括号括起来的. 2.python中的中括号[ ...

  8. C# Self Injector into non managed process

    Hey all, I'm gonna explain you how make a self injecting program in C#.I hope you guys thinks its us ...

  9. 2.2寸(14PIN)TFT液晶屏STM32 SPI 控制

    屏幕如图所示,共14个IO口(也可能只有13个),控制屏幕的有9个IO口 详细版介绍见:http://www.ciast.net/post/20151112.html 反面IO口图: 连接通过SPI方 ...

  10. Linux随笔 - Linux LVM逻辑卷配置过程详解[转载]

    许多Linux使用者安装操作系统时都会遇到这样的困境:如何精确评估和分配各个硬盘分区的容量,如果当初评估不准确,一旦系统分区不够用时可能不得不备份.删除相关数据,甚至被迫重新规划分区并重装操作系统,以 ...