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 ...
随机推荐
- css盒子模型的宽度不包括margin
看到教程上和一些博客上盒子模型的宽度 = content + padding + margin + border,应该是不包括margin的 <!DOCTYPE html> <htm ...
- struts2中的Action实现的三种方式
Action类创建方式有哪些? 方式一:直接创建一个类,可以是POJO,即原生Java类,没有继承任何类,也没有实现任何接口 这种方式使得strust2框架的代码侵入性更低,但是这种方式是理想状态,开 ...
- SERVLET API中转发与重定向的区别?
SERVLET API中转发与重定向的区别? 1.转发(forward方法) 转发仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址. 转发是服务器请求资源,服务器直接访问目标地址的 ...
- 03.父工程pom、整合测试、SpringBootApplication注解
父工程 idea点击spring-boot-starter-parent找到父工程spring-boot-dependencies模仿配置 父工程 <?xml version="1.0 ...
- BiNGO的GO分析
GO富集分析对老师们来说想必都不陌生,几乎在任何项目中都会出现.今天就给大家介绍一款简单易学又好用的富集分析小软件---BiNGO.它是Cytoscape软件中很出色的一个插件.它提供的结果中除了文本 ...
- C++ 概率算法 利用蒙特卡罗算法计算圆周率
概率算法大致可分为4种形式: 数值概率算法: 蒙特卡罗算法: 拉斯维加斯算法: 舍伍德算法: 计算蒙特卡罗概率的算法实现: #include "stdio.h" #include ...
- DOS基础使用专题(强烈推荐)2
DOS下硬件设备的使用与设置 由于电脑的普及和应用的日益深入,为了满足人们的需要,电脑的功能随着它的发展变得越来越强大,硬件设备也越来越多,如从原来的ISA及PCI声卡.调制解调器等到现在的USB硬盘 ...
- 540D - Bad Luck Island(概率DP)
原题链接:http://codeforces.com/problemset/problem/540/D 题意:给你石头.剪刀.布的数量,它们之间的石头能干掉剪刀,剪刀能干掉布,布能干掉石头,问最后石头 ...
- Rainbow的信号 CH3801
题目链接 题意:求n个整数任意取一个区间,一起进行xor,and,或or的操作,求xor的期望值,and的期望值,or的期望值. 思路:区间取的左端点为l,右端点为r,当r==l时,选的概率为1/n/ ...
- bugku | 你从哪里来
题目链接 之前一直以为要用x-forwarded-for ,谁道用的是referer,Orz.在此特地记录,x-forwarded-for 和 referer的区别 X-Forwarded-For(X ...