题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3874 , 线段树(或树状数组) + 离线处理

  下午做了第一道离线处理的题目(HDU4417),多少有点感觉,顺便就把这道题也给做了。


  这道题就是要求某个区间内不重复数的和,自己在网上百度后参考别人的方法才AC的。参考来源:http://www.cnblogs.com/gj-Acit/p/3249827.html

  这道题还是需要先离线处理数据,具体方法:

  ① 先用线段树把树给建立起来;

  ② 先把所有要查询的区间存起来,按照区间的右边界的大小从小到大排序,注意保存下标;

    ③ 对于排序后的每次询问要这样处理:把上次询问区间的右边界到当前询问的右边界中的这些数字进行处理,如果这些数字在之前出现过,则把之前出现的这个数字给删掉(置0即可),然后单点更新线段树;然后查询的话用线段树进行区间求和即可。

  我参考的方法中是这样处理的,即用一个数组vis[]存储数字a[i]第一次出现的位置,后来扫描的时候如果发现 vis[a[i]] != i ,即说明该数字之前出现过。

  最后注意这里用int储存结果会爆掉的,所以要用__int64.

#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL __int64
#define eps 1e-8
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int MOD = ;
const int maxn = + ;
const int N = + ;
LL sum[maxn << ] , ans[maxn << ]; //sum[]存线段树,ans[]存结果
int vis[N] , a[maxn]; //vis[]第一次出现的位置,a[]存储叶子节点信息
struct Section { //区间
int L , R;
int index;
bool operator < (const Section tmp) const {
return R < tmp.R;
}
} s[maxn << ];
void PushUp(int rt)
{
sum[rt] = sum[rt << ] + sum[rt << | ];
}
void build()
{
memset(sum , , sizeof(sum));
memset(vis , , sizeof(vis));
}
void update(int pos , int x , int l , int r , int rt)
{
if(l == r) {
sum[rt] = x;
return;
}
int m = (l + r) >> ;
if(pos > m)
update(pos , x , rson);
else
update(pos , x , lson);
PushUp(rt);
}
LL query(int L , int R , int l , int r , int rt)
{
if(L <= l && R >= r) {
return sum[rt];
}
int m = (l + r) >> ;
if(m < L)
return query(L , R , rson);
else if(m >= R)
return query(L , R , lson);
else
return query(L , R , lson) + query(L , R , rson);
}
int main()
{
int T , i , j , n , m;
cin >> T;
while(T--)
{
build();
scanf("%d" , &n);
for(i = ; i <= n ; i++) {
scanf("%d" , &a[i]);
if(!vis[a[i]]) //a[i]第一次出现的位置
vis[a[i]] = i;
update(i , a[i] , , n , ); //实际是在这里建的树
}
scanf("%d" , &m);
for(i = ; i <= m ; i++) {
scanf("%d %d" , &s[i].L , &s[i].R);
s[i].index = i;
}
sort(s + , s + m + );
for(i = , s[].R = ; i <= m ; i++) { //此为步骤③
for(j = s[i - ].R ; j <= s[i].R ; j++) {
if(vis[a[j]] != j) {
int tmp = vis[a[j]];
update(tmp , , , n , ); //删掉之前出现的该数字
vis[a[j]] = j; //删掉后再换位置
}
}
ans[s[i].index] = query(s[i].L , s[i].R , , n , );
}
for(i = ; i <= m ; i++)
printf("%I64d\n" , ans[i]);
}
return ;
}

HDU3874 线段树 + 离线处理的更多相关文章

  1. 线段树+离线 hdu5654 xiaoxin and his watermelon candy

    传送门:点击打开链接 题意:一个三元组假设满足j=i+1,k=j+1,ai<=aj<=ak,那么就好的.如今告诉你序列.然后Q次询问.每次询问一个区间[l,r],问区间里有多少个三元组满足 ...

  2. 牛客练习赛53 E-老瞎眼pk小鲜肉(思维+线段树+离线)

    前言 听说是线段树离线查询?? 做题做着做着慢慢对离线操作有点感觉了,不过也还没参透,等再做些题目再来讨论离线.在线操作. 这题赛后看代码发现有人用的树状数组,$tql$.当然能用树状数组写的线段树也 ...

  3. HDU 4638-Group(线段树+离线处理)

    题意: 给n个编号,m个查询每个查询l,r,求下标区间[l,r]中能分成标号连续的组数(一组内的标号是连续的) 分析: 我们认为初始,每个标号为一个组(线段树维护区间组数),从左向右扫序列,当前标号, ...

  4. HDU 4630-No Pain No Game(线段树+离线处理)

    题意: 给你n个数的序列a,q个询问,每个询问给l,r,求在下标i在[l,r]的区间任意两个数的最大公约数中的最大值 分析: 有了hdu3333经验,我们从左向右扫序列,如果当前数的约数在前面出现过, ...

  5. HDU 4288 Coder 【线段树+离线处理+离散化】

    题意略. 离线处理,离散化.然后就是简单的线段树了.需要根据mod 5的值来维护.具体看代码了. /* 线段树+离散化+离线处理 */ #include <cstdio> #include ...

  6. SPOJ--K-query (线段树离线) 离线操作解决一些问题

    K-query Given a sequence of n numbers a1, a2, ..., an and a number of k- queries. A k-query is a tri ...

  7. lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs 倍增

    https://www.luogu.org/problemnew/show/P3379 1.欧拉序+rmq(st) /* 在这里,对于一个数,选择最左边的 选择任意一个都可以,[left_index, ...

  8. 51nod 1463 找朋友(线段树+离线处理)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序, ...

  9. 玲珑oj 1117 线段树+离线+离散化,laz大法

    1117 - RE:从零开始的异世界生活 Time Limit:1s Memory Limit:256MByte Submissions:438Solved:68 DESCRIPTION 486到了异 ...

随机推荐

  1. 【service调用dao层传参的三种方式】

    第一种方案:默认数组角标: service Public User selectUser(String name,String area); mapper: <select id="s ...

  2. Cactus项目(又叫MVCAdmin),开源(2016-11-26更新)

    Cactus基于之前简单后台管理的改良版本,完善了权限管理,为后续的扩展和管理做了铺垫. 完全开放代码,可供学习交流 目前采用MVC4+Autofac+Dapper制作而成,集成一个简单的Blog和权 ...

  3. java线程基础知识----java线程模型

    转载自http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html 1. 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标 ...

  4. php5.6安装window7安装memcache.dll库所遇到的误区

    问题: window7 64位,下载的库 memcache.dll 为64位的,且对应php的版本.但是重启后phpstudy查看phpinfo依然没有memcache: 根源: 发现是下载的 mem ...

  5. iOS开发之swift与OC混编出现的坑,oc中不能对swift的代理进行调用,不能访问swift中的代理,swift中的回调方法

    1. Swift与oc混编译具体怎么实现,这儿我就不重复讲出了,网上有大把的人讲解. 2. 在swift与OC混编的编译环境下, oc类不能访问swift创建类中的代理? 解决方法如下: 在代理的头部 ...

  6. LDAP--对某些AD属性值是字节数组byte[]情况的类型转换方法

    //BitConverter.ToBoolean((searchResult.Properties["mDBUseDefaults"][0] as byte[]), 0); row ...

  7. aspnetcore配置log4net并添加全局异常处理

    第一步:在NuGet中引用log4net 第二步:创建log4net.config <?xml version="1.0" encoding="utf-8" ...

  8. 转 oracle数据仓库部署注意事项(OLAP)

    https://blog.csdn.net/laven54/article/details/9840365 最近数据库升级到11G之后,出现一些问题,慢慢的开始发现一些需要总结的东西,每次心里都在想: ...

  9. POJ - 3450

    题目链接:http://poj.org/problem?id=3450 Corporate Identity Time Limit: 3000MS   Memory Limit: 65536K Tot ...

  10. 车牌号校验js

    var regExp = /(^[\u4E00-\u9FA5]{1}[A-Z0-9]{6}$)|(^[A-Z]{2}[A-Z0-9]{2}[A-Z0-9\u4E00-\u9FA5]{1}[A-Z0-9 ...