HDU-3333 Turing 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 分块求区间不同数和的更多相关文章
- SPOJ D-query && HDU 3333 Turing Tree (线段树 && 区间不相同数个数or和 && 离线处理)
题意 : 给出一段n个数的序列,接下来给出m个询问,询问的内容SPOJ是(L, R)这个区间内不同的数的个数,HDU是不同数的和 分析 : 一个经典的问题,思路是将所有问询区间存起来,然后按右端点排序 ...
- HDU 3333 Turing Tree 线段树+离线处理
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Othe ...
- 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 (主席树)
题意:给定上一个序列,然后有一些询问,求区间 l - r 中有多少个不同的数的和. 析:和求区间不同数的方法是一样,只要用主席树维护就好. 代码如下: #pragma comment(linker, ...
- 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 (线段树)
Turing Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 3333 Turing Tree 离线 线段树/树状数组 区间求和单点修改
题意: 给一个数列,一些询问,问你$[l,r]$之间不同的数字之和 题解: 11年多校的题,现在属于"人尽皆知傻逼题" 核心思想在于: 对于一个询问$[x,R]$ 无论$x$是什么 ...
- HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)
题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...
- HDU 3333 Turing Tree (树状数组)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3333 题意就是询问区间不同数字的和. 比较经典的树状数组应用. //#pragma comment(l ...
随机推荐
- 洛谷4843 BZOJ2502 清理雪道
有源汇有上下界的最小可行流. YY一下建图应该很好搞吧(? 就是对于每个雪道都是[1,inf]然后源点到所有点都是[0,inf]所有点到汇点都是[0,inf] 这样的话跑一个有源汇上下界最小可行流就可 ...
- 《嵌入式软件设计基础——基于ARM Cortex—M3》读书笔记
此书有点深,记录点自己能够看懂的. 1.内存管理一章:讲到变量的类型.生存周期.内存分配. auto static register 局部变量,全局变量 malloc free 内存碎片,消除内存池的 ...
- 0-2马尔可夫过程Markov Processes
在0-1中提到了,当最终output的p=0时,这个时候模型无法正常使用,为了解决这个问题,在0-4中会有所提及. 在本节中,其实,计算概率的时候,我们应该假设某一个位置的词与它前面的所有词都是相关的 ...
- 高精度乘法模板(luogu1303)
洛谷1303 //luogu1303,不压位的高精度乘法 #include <cstdio> #include <iostream> using namespace std; ...
- 【LeetCode 42】接雨水
题目链接 [题解] 考虑每个位置它最后能接多少单位的水. 显然就是这个min(位置左边最高的位置,位置右边最高的位置)-当前这个位置的高度. 这就是这个位置最后水上涨的高度. 两个边界注意是不会储水的 ...
- http_load(基于linux平台的一种性能测试工具)
http_load 是运行在linux操作系统上的命令行测试工具, 用来对网站做压力测试.http_load以并行复用的方式运行,用以测试web服务器的吞吐量和负载.但是它不同于大多数压力测试工具, ...
- H5页面二次分享
对于H5页面来说二次分享还是蛮重要的,毕竟qq还是微信发出去之后习惯性的使用自带的分享功能.和PC端不同,PC直接复制地址了.前两天在做请柬,踩了不少的雷,个人开发和公司开发还是不一样,各种问题,其他 ...
- (转)Groovy简介
转:https://www.w3cschool.cn/groovy/ Groovy的官方网站是http://www.groovy-lang.org/ Groovy是一种基于JVM(Java虚拟机)的敏 ...
- MySQL 获取本月第一天、下个月第一天等
select curdate(); --获取当前日期 select last_day(curdate()); --获取当月最后一天. select DATE_ADD(curdate(),interva ...
- MATLAB 中几个颜色空间的坐标范围
在一些图象处理的程序中,我们经常要在不同的颜色空间操作,而且经常要把各颜色空间的坐标转化到 [0,1] 之间,这就需要知道一些常用颜色空间的坐标范围. 虽然可以通过颜色空间转化的公式推导这些范围,但是 ...