HDU3874 线段树 + 离线处理
题目链接: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 线段树 + 离线处理的更多相关文章
- 线段树+离线 hdu5654 xiaoxin and his watermelon candy
传送门:点击打开链接 题意:一个三元组假设满足j=i+1,k=j+1,ai<=aj<=ak,那么就好的.如今告诉你序列.然后Q次询问.每次询问一个区间[l,r],问区间里有多少个三元组满足 ...
- 牛客练习赛53 E-老瞎眼pk小鲜肉(思维+线段树+离线)
前言 听说是线段树离线查询?? 做题做着做着慢慢对离线操作有点感觉了,不过也还没参透,等再做些题目再来讨论离线.在线操作. 这题赛后看代码发现有人用的树状数组,$tql$.当然能用树状数组写的线段树也 ...
- HDU 4638-Group(线段树+离线处理)
题意: 给n个编号,m个查询每个查询l,r,求下标区间[l,r]中能分成标号连续的组数(一组内的标号是连续的) 分析: 我们认为初始,每个标号为一个组(线段树维护区间组数),从左向右扫序列,当前标号, ...
- HDU 4630-No Pain No Game(线段树+离线处理)
题意: 给你n个数的序列a,q个询问,每个询问给l,r,求在下标i在[l,r]的区间任意两个数的最大公约数中的最大值 分析: 有了hdu3333经验,我们从左向右扫序列,如果当前数的约数在前面出现过, ...
- HDU 4288 Coder 【线段树+离线处理+离散化】
题意略. 离线处理,离散化.然后就是简单的线段树了.需要根据mod 5的值来维护.具体看代码了. /* 线段树+离散化+离线处理 */ #include <cstdio> #include ...
- 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 ...
- lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs 倍增
https://www.luogu.org/problemnew/show/P3379 1.欧拉序+rmq(st) /* 在这里,对于一个数,选择最左边的 选择任意一个都可以,[left_index, ...
- 51nod 1463 找朋友(线段树+离线处理)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序, ...
- 玲珑oj 1117 线段树+离线+离散化,laz大法
1117 - RE:从零开始的异世界生活 Time Limit:1s Memory Limit:256MByte Submissions:438Solved:68 DESCRIPTION 486到了异 ...
随机推荐
- LeetCode: 453 Minimum Moves to Equal Array Elements(easy)
题目: Given a non-empty integer array of size n, find the minimum number of moves required to make all ...
- nfs使用教程
服务端 配置说明 文件名 /etc/exports 格式 <输出目录> [客户端 (访问权限,用户映射,其他) ] [客户端 (访问权限,用户映射,其他) ] 格式说明 输出目录:NFS系 ...
- 洛谷P2607 [ZJOI2008]骑士
P2607 [ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一 ...
- Taran 缩点【bzoj1529】[POI2005]ska Piggy banks
[bzoj1529][POI2005]ska Piggy banks Description Byteazar 有 N 个小猪存钱罐. 每个存钱罐只能用钥匙打开或者砸开. Byteazar 已经把每个 ...
- 旅行青蛙分析(Android篇)
近期旅行青蛙这款游戏非常的火热,周围的朋友.家人都养了一只小青蛙.看到网上有人说这款游戏可以直接逆向编译,没有加密:所以在搜索相关资料后花了一些时间进行逆向分析与修改.这篇文章里,我将介绍如何获取稀有 ...
- 影子内存(Shadow RAM)介绍_4
影子内存(Shadow RAM,或称ROM shadow)是为了提高系统效率而采用的一种专门技术.它把系统主板上的系统ROM BIOS和适配器卡上的视频ROM BIOS等拷贝到系统RAM内存中去运行, ...
- 【Linux】Linux常用命令大全
系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS ...
- 打印流-PrintStream
打印流-PrintStream java.io.PrintStream为其他输出流添加了功能,使其他的流能够更方便的打印各种数据值表现形式 PrintStream特点: 1.只负责数据的输入,不负责数 ...
- vulhub-php/php_inclusion_getshell
注:本地测试php文件包含+phpinfo泄露导致getshell,此漏洞与php版本无关 使用vulhub环境进行复现: 项目地址:https://github.com/vulhub/vulhub/ ...
- angularjs $state.go页面不刷新数据
假如进入market/beian/add添加数据,保存提交后回退market/beian列表页,没有自动更新数据,必须得手动下拉刷新才会出来 $state.go("marketBeian&q ...