hdu 3333 树状数组+离线处理
思路:既然要求的是不同的元素的和,那么我们可以想办法让每个值在区间中只出现一次,于是想到了离线的算法:将查询按照右端点排序,位置在右端点之前的元素都插入到树状数组中,对于已经出现过的值,我们要先删除(在原位置)再插入(在cur的位置),因为很显然对于同一个元素,只有在最靠右的位置出现一次才能返回正确的查询结果。所以我们需要用map来记录每个值上一次插入的位置,删除后再插入到当前位置。
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <map> 6 using namespace std; 7 8 typedef long long ll; 9 const int N = 30001; 10 const int Q = 100001; 11 ll c[N]; 12 ll ans[Q]; 13 int a[N]; 14 15 struct Query 16 { 17 int i, j, id; 18 bool operator < ( const Query & o ) const 19 { 20 return j < o.j; 21 } 22 } query[Q]; 23 24 map<int, int> mp; 25 26 int lb( int i ) 27 { 28 return i & -i; 29 } 30 31 void update( int i, int v ) 32 { 33 while ( i < N ) 34 { 35 c[i] += v; 36 i += lb(i); 37 } 38 } 39 40 ll get( int i ) 41 { 42 ll ans = 0; 43 while ( i ) 44 { 45 ans += c[i]; 46 i -= lb(i); 47 } 48 return ans; 49 } 50 51 int main () 52 { 53 int t; 54 scanf("%d", &t); 55 while ( t-- ) 56 { 57 int n, q; 58 scanf("%d", &n); 59 for ( int i = 1; i <= n; i++ ) 60 { 61 scanf("%d", a + i); 62 } 63 scanf("%d", &q); 64 for ( int i = 1; i <= q; i++ ) 65 { 66 scanf("%d%d", &query[i].i, &query[i].j); 67 query[i].id = i; 68 } 69 sort( query + 1, query + 1 + q ); 70 memset( c, 0, sizeof(c) ); 71 mp.clear(); 72 int cur = 1; 73 for ( int i = 1; i <= q; i++ ) 74 { 75 while ( cur <= query[i].j ) 76 { 77 if ( mp.count(a[cur]) ) 78 { 79 int pos = mp[a[cur]]; 80 update( pos, -a[cur] ); 81 } 82 update( cur, a[cur] ); 83 mp[a[cur]] = cur; 84 cur++; 85 } 86 ans[query[i].id] = get( query[i].j ) - get( query[i].i - 1 ); 87 } 88 for ( int i = 1; i <= q; i++ ) 89 { 90 printf("%I64d\n", ans[i]); 91 } 92 } 93 return 0; 94 }
转载于:https://www.cnblogs.com/huoxiayu/p/4687224.html
hdu 3333 树状数组+离线处理相关推荐
- hdu 4417(树状数组+离线算法)
解题思路:这道题要求某区间内比h小的个数,其实这里可以类似于树状数组求逆序数那样.关键是如何转换成树状数组的模型,这才是本题的难点. 我们首先分析,如果知道h在该区间的哪个位置,那么剩下的就很好做了. ...
- HDU 4358 树状数组+思路
http://acm.hdu.edu.cn/showproblem.php?pid=4358 如图所示,当k==3时,如果我们扫描到红线所在的位置. 则符合条件的区间就是从红线到两条紫线所包含的区间( ...
- hdu 4991(树状数组优化dp)
Ordered Subsequence Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- Sereja and Brackets CodeForces - 380C (树状数组+离线)
Sereja and Brackets 题目链接: CodeForces - 380C Sereja has a bracket sequence s1, s2, ..., *s**n, or, in ...
- hdu 1166 树状数组解
树状数组解决 (关于树状数组参考大佬的博客https://www.cnblogs.com/hsd-/p/6139376.html) 然后就很好理解这题了,代码附上 /*hdu 1166 单点修改, ...
- SPOJ D-query 树状数组离线 求区间内不同数字的个数
Given a sequence of n numbers a1, a2, -, an and a number of d-queries. A d-query is a pair (i, j) (1 ...
- 2019 南京 网络赛 B (二维偏序,树状数组离线)
题意: 给出一N*N的蛇形矩阵,具体位置元素值不给你,自己找规律,然后给你M个 有效位置,P次查询,每次查询一个子矩阵中有效元素的权值和,该权值和等于对于 每个有效元素,模10拆分后相加得到的和.(注 ...
- hdu 1394(树状数组求逆序数)
解题思路:这道题是求循环数组中逆序数最小值,求逆序数这里肯定是用树状数组.只是这里有一点点变化,由于题目中n位数是0-n-1的一个排列,所以num[i]可表示为比num[i]小的数的个数.把第一位的数 ...
- Weak Pair HDU - 5877 树状数组+离散化+DFS遍历
题意 给我们一颗有根有向树 以及每个点得权值a[1]~a[n] 需要我们求出在这颗树种有多少对满足以下两个条件的pair (1)u是v的祖先节点 (2)a[u]*a[v]<= k N<=1 ...
最新文章
- 原 ng-include用法分析以及多标签页面的简单实现方式
- vscode使用教程python-VsCode使用教程
- 科研实习 | 北京大学智能学院贺笛老师招收NLP/GNN方向科研实习生
- BZOJ 1683.City skyline 城市地平线
- git checkout 单个文件_git 如何回退单个文件
- P5299-[PKUWC2018]Slay the Spire【dp】
- 重磅!彭博社“机器学习基础”教程视频及讲义下载
- 这家公司的 IoT ,你可千万别低估!
- 《OpenGL编程指南》一第3章 OpenGL绘制方式
- 大数据实验室(大数据基础培训)——Kafka的安装、配置及基础使用
- 算法复习周------“动态规划之‘图像压缩’”
- html调整浏览器兼容性,浏览器兼容性问题整理
- 直播带货那么火,测试人员如何对直播类产品的直播质量进行测试呢?
- 2021年全球与中国红外窗口行业市场规模及发展前景分析
- 将信将疑,将中台进行到底
- java编写抖音上图片转文字的程序
- React高频面试题总结 (附答案及原理代码)
- wordpress文章ID不连续显示问题的完美解决
- 百万爆文怎么出现的?这个规则很多人不懂
- 轮式机器人算法仿真的一些杂七杂八03