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 ...
随机推荐
- 前端学习(三十四)对象&模块化(笔记)
人,工人 //类的定义 function Person(name,age){ //构造函数 //工厂模式 //1.原料 //var obj = new ...
- torchvision.transforms模块介绍
torchvision.transforms模块 官网地址:https://pytorch.org/docs/stable/torchvision/transforms.html# torchvisi ...
- BZOJ1899 [Zjoi2004]Lunch 午餐 贪心+DP
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1899 题解 如果只有一个窗口,那么可以这样考虑:因为最后一个人打完饭的时间是固定的,那么不如就 ...
- 使用stylelint进行Vue项目样式检查
stylelint是一个强大的现代 CSS 检测器,可以让开发者在样式表中遵循一致的约定和避免错误.拥有超过170条的规则,包括捕捉错误.最佳实践.控制可以使用的语言特性和强制代码风格规范.它支持最新 ...
- linux查找一个文件的路径
- 查完数据库order_by后跟[:9]切片取前9位的值
- MySQL索引优化之双表示例
select * from tableA a left join tableB b on a.f_id = b.id; 索引建tableB表上面, 因为left join 注定左表全都有,所以应该关心 ...
- @encode关键字
@encode() 为了更好的互操作性,Objective-C 的数据类型,甚至自定义类型.函数或方法的元类型,都可以使用 ASCII 编码.@encode(aType) 可以返回该类型的 C 字符串 ...
- YII 1.0 常用CURD写法
<?php //yii1.0 curd简单写法 //查询 Yii::app()->db->createCommand($sql)->queryAll();//查询所有行数据 ...
- php开发面试题---日常面试题1
php开发面试题---日常面试题1 一.总结 一句话总结: 实战确定学习方向,然后去网上找视频资源,非常多,然后看书 1.什么样的数据存在memcache里面? 要去数据库里面查询的那些数据,数据库查 ...