题目在这里

3368 Accepted 7312K 1829MS C++ 6936B

题意为给你一组数据,再给定一组区间,问你这个区间内出现次数最多的元素的次数是多少。

我还记得这题是学校校赛基础的题目,当时懵懵懂懂的用分治交了6次TLE。知道了线段树之后才后悔每更早的认识她。

一段区间内的多次出现的数的次数,在线段树查询中有以下几种情况

1.次数最多的都集中在某一结点的左区间内

2.次数最多的都集中在某一结点的有区间内

3.次数最多的在左右两边都有,这时maxCount ==左右两边的maxCount之和

在增加时,如果要加的区间正好覆盖一个节点,则增加其节点的Inc值,不再往下走,否则要更新nSum(加上本次增量),再将增量往下传。这样更新的复杂度就是O(log(n))在查询时,如果待查区间不是正好覆盖一个节点,就将节点的Inc往下带,然后将Inc代表的所有增量累加到nSum上后将Inc清0,接下来再往下查询。

  1. /*************************************************************************
  2. > File Name: poj3368rmq.cpp
  3. > Author: YeGuoSheng
  4. > Description:
  5. > Created Time: 2019年07月11日 星期四 15时34分56秒
  6. ************************************************************************/
  7.  
  8. #include<iostream>
  9. #include<stdio.h>
  10. #include<cstring>
  11. #include<cmath>
  12. #include<vector>
  13. #include<stack>
  14. #include<map>
  15. #include<set>
  16. #include<list>
  17. #include<queue>
  18. #include<string>
  19. #include<algorithm>
  20. #include<iomanip>
  21. using namespace std;
  22.  
  23. template <typename T>
  24. struct node
  25. {
  26. int l;
  27. int r;//左右区间端点
  28. T value;
  29. T add;
  30. int lCount;//元素在左边的计数
  31. int rCount;//元素在右边的计数
  32. int maxCount;//总计出现的次数
  33. int Len()const;
  34. int Mid()const;
  35. };
  36.  
  37. template <typename T>
  38. int node<T>::Mid()const
  39. {
  40. return (r + l )/ ;
  41. }
  42.  
  43. template<typename T>
  44. int node<T>::Len()const
  45. {
  46. return (r - l ) +;
  47. }
  48.  
  49. template<typename T>
  50. class IntervalTree
  51. {
  52. protected:
  53. int n;
  54. node<T>*tree;
  55. public:
  56. IntervalTree(int n);
  57. ~IntervalTree();
  58. void BuildTree(int v,int l,int r);
  59. void Add(int v,int l,int r,T m);
  60. T Query(int v,int l,int r);
  61. void Insert(int v,int i,T value);
  62. void BuildCount(int v,int l,int r);
  63. int FindIndexInTree(int v,int y);//在数组下标为u的在树中的下标
  64. };
  65.  
  66. template<typename T>
  67. IntervalTree<T>::IntervalTree(int n)
  68. {
  69. this->n = n;
  70. tree = new node<T>[*n];
  71. }
  72.  
  73. template<typename T>
  74. IntervalTree<T>::~IntervalTree()
  75. {
  76. delete []tree;
  77. }
  78.  
  79. template<typename T>
  80. void IntervalTree<T>::BuildTree(int v ,int l,int r)
  81. {
  82. tree[v].l =l;
  83. tree[v].r = r;
  84. tree[v].add = ;
  85. tree[v].value = ;
  86. if(l == r)//相等
  87. {
  88. tree[v].lCount =tree[v].rCount = tree[v].maxCount = ;
  89. return ;
  90. }
  91. int mid =(l + r) /;//二分
  92. BuildTree(v* +,l,mid);
  93. BuildTree(v*+,mid+,r);
  94. tree[v].value = tree[*v+].value + tree[*v+].value;
  95. }
  96.  
  97. template<typename T>
  98. int IntervalTree<T>::FindIndexInTree(int v,int u)
  99. {
  100. if( tree[v].l == u && tree[v].r == u)
  101. {
  102. return v;
  103. }
  104. else
  105. {
  106. int mid = (tree[v].l + tree[v].r) / ;
  107. if(u <= mid)
  108. {
  109. FindIndexInTree(v * +,u);
  110. }
  111. else
  112. {
  113. FindIndexInTree(v * +,u);
  114. }
  115. }
  116. }
  117.  
  118. template<typename T>
  119. void IntervalTree<T>::BuildCount(int v,int l ,int r)
  120. {
  121. tree[v].l = l;
  122. tree[v].r = r;
  123. if(l == r)
  124. {
  125. tree[v].lCount = tree[v].rCount =tree[v].maxCount = ;
  126. return ;
  127. }
  128. int mid = (l + r )/ ;
  129. BuildCount(* v+ ,l,mid);
  130. BuildCount(*v +,mid+,r);
  131. int repeat = ;
  132. int leftIndex = FindIndexInTree(v,tree[*v+].r);
  133. int rightIndex = FindIndexInTree(v,tree[*v+].l);
  134. if(tree[leftIndex].value == tree[rightIndex].value)
  135. {
  136. repeat = tree[ * v +].rCount + tree[*v +].lCount;
  137. }
  138. else
  139. {
  140. repeat = ;
  141. }
  142. tree[v].maxCount = max( repeat,max( tree[*v+].maxCount, tree[*v+].maxCount) );
  143. tree[v].lCount = tree[*v+].lCount;
  144. if(tree[*v + ].lCount == mid - l + && tree[leftIndex].value==tree[rightIndex].value)
  145. {
  146. tree[v].lCount += tree[*v +].lCount;
  147. }
  148. if(tree[*v + ].rCount == r- mid && tree[rightIndex].value==tree[leftIndex].value)
  149. {
  150. tree[v].rCount += tree[*v +].rCount;
  151. }
  152. }
  153. template<typename T>
  154. void IntervalTree<T>::Add(int v,int l,int r,T m)//区间的更新操作
  155. {
  156. if(tree[v].l == l && tree[v].r == r)
  157. {
  158. tree[v].add +=m;
  159. return ;
  160. }
  161. tree[v].value += m * (r- l +);
  162. int mid = (tree[v].l + tree[v].r) /;
  163. if( r<= mid)
  164. {
  165. Add(v * +,l,r,m);
  166. }
  167. else
  168. {
  169. if(l > mid)
  170. {
  171. Add(v * +,l,r,m);
  172. }
  173. else
  174. {
  175. Add(v * +,l,mid,m);
  176. Add(v*+,mid+,r,m);
  177. }
  178.  
  179. }
  180.  
  181. }
  182. template<typename T>
  183. T IntervalTree<T>::Query(int v,int l,int r)//对根结点为v,查询区间l 到 r
  184. {
  185. if(tree[v].l == l && tree[v].r == r)
  186. {
  187. return tree[v].value +(tree[v].r - tree[v].l +) * tree[v].add;
  188. }
  189. if(tree[v].add != )
  190. {
  191. tree[v].value += (tree[v].r - tree[v].l +) * tree[v].add;
  192. Add( v * +,tree[v].l,tree[v].Mid(),tree[v].add);
  193. Add( v * +,tree[v].Mid()+,tree[v].r,tree[v].add);
  194. tree[v].add = ;
  195. }
  196. int mid = tree[v].Mid();
  197. if( r <= mid)
  198. {
  199. return Query(v * +,l,r);
  200. }
  201. else
  202. {
  203. if( l > mid)
  204. {
  205. return Query(v * + ,l ,r);
  206. }
  207. else
  208. {
  209. return Query(v * +,l,mid) + Query(v* +,mid+,r);
  210. }
  211. }
  212. }
  213.  
  214. template<typename T>
  215. void IntervalTree<T>::Insert(int r,int i,T value)
  216. {
  217. if(tree[r].l == i && tree[r].r == i)
  218. {
  219. tree[r].value= value;
  220. return ;
  221. }
  222. tree[r].value += value;
  223. if(i <= tree[r].Mid())
  224. {
  225. Insert(*r+,i,value);
  226. }
  227. else
  228. {
  229. Insert( * r+ ,i,value);
  230. }
  231. }
  232.  
  233. int main()
  234. {
  235. int n = ;
  236. while(cin>>n && n > )
  237. {
  238. IntervalTree<int> it(n);
  239. it.BuildTree(,,n-);
  240. int q = ;
  241. scanf("%d",&q);
  242. for(int i = ; i< n;i++)
  243. {
  244. int num = ;
  245. scanf("%d",&num);
  246. it.Insert(,i,num);
  247. }
  248. it.BuildCount(,,n-);
  249. for(int i = ;i < q;i++)
  250. {
  251. int x,y;
  252. cin>>x>>y;
  253. cout<<it.Query(,x-,y-)<<endl;
  254. }
  255. }
  256. return ;
  257. }

POJ3368(Frequent values)--线段树的更多相关文章

  1. HDOJ-1806 ( Frequent values ) 线段树区间合并

    http://acm.hdu.edu.cn/showproblem.php?pid=1806 线段树维护区间出现频率最高的出现次数.为了维护上者,需要维护线段前后缀的出现次数,当和其他线段在端点处的字 ...

  2. UVA 11235 Frequent values 线段树/RMQ

    vjudge 上题目链接:UVA 11235 *******************************************************大白书上解释**************** ...

  3. POJ 3368 Frequent values 线段树与RMQ解法

    题意:给出n个数的非递减序列,进行q次查询.每次查询给出两个数a,b,求出第a个数到第b个数之间数字的最大频数. 如序列:-1 -1 1 1 1 1 2 2 3 第2个数到第5个数之间出现次数最多的是 ...

  4. hdu 1806 Frequent values 线段树

    题目链接 给一个非递减数列, n个数, m个询问, 每个询问给出区间[L, R], 求这个区间里面出现次数最多的数的次数. 非递减数列, 这是最关键的一个条件... 需要保存一个区间最左边的数, 最右 ...

  5. poj3368 Frequent values(线段树)

    Description You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In ad ...

  6. POJ3368 Frequent values(RMQ线段树)

    题目大概说给一个递增序列,询问区间出现最多的数. 用莫队算法比较直观,虽然应该会T..好像也可以主席树..不过题目给的序列是有序的,因而相同的数会聚在一起. 考虑把序列分成一段一段,使每段都包含极大的 ...

  7. [poj3368]Frequent values(rmq)

    题意:给出n个数和Q个询问(l,r),对于每个询问求出(l,r)之间连续出现次数最多的次数. 解题关键:统计次数,转化为RMQ问题,运用st表求解,注意边界. 预处理复杂度:$O(n\log n)$ ...

  8. poj3368 Frequent values

    思路: 转化为RMQ. 实现: #include <cstdio> #include <cstring> #include <algorithm> using na ...

  9. POJ 3368 Frequent values RMQ ST算法/线段树

                                                         Frequent values Time Limit: 2000MS   Memory Lim ...

随机推荐

  1. Python设计模式之MVC模式

    # -*- coding: utf-8 -*- # author:baoshan quotes = ('A man is not complete until he is married. Then ...

  2. openresty开发系列23--lua面向对象

    openresty开发系列23--lua面向对象 面向对象编程(Object Oriented Programming,OOP)是一种非常流行的计算机编程架构.java,c++,.net等都支持面向对 ...

  3. postgresql 利用pgAgent实现定时器任务

    1.安装pgAgent 利用Application Stack Builder安装向导,安装pgAgent. 根据安装向导一步一步安装即可. 安装完成之后,windows服务列表中会增加一个服务:Po ...

  4. Js/jQuery实时监听input输入框值变化

    前言在做web开发时候很多时候都需要即时监听输入框值的变化,以便作出即时动作去引导浏览者增强网站的用户体验感.而采用onchange时间又往往是在输入框失去焦点(onblur)时候触发,有时候并不能满 ...

  5. SeetaFace2 cmake VS2015编译编译

    cmake Selecting Windows SDK version 10.0.17134.0 to target Windows 10.0.18362. == BUILD_VERSION: v2. ...

  6. Linux记录-Nginx+Tomcat负载均衡配置

    Nginx负载均衡配置及策略: 轮询(默认) 优点:实现简单缺点:不考虑每台服务器的处理能力配置示例如下:upstream www.xxx.com {# 需要负载的server列表server www ...

  7. python flask框架学习(一)——准备工作和环境配置与安装

    Flask装备: 学习自:知了课堂Python Flask框架——全栈开发 1.Python版本:3.6 2.Pycharm软件: 3.安装虚拟环境: (1)安装virtualenv: pip ins ...

  8. Python - Django - 模板语言之变量

    前言: 在 Django 模板语言中变量用 {{ }},逻辑用 {% %} 在 urls.py 中添加对应关系 from django.conf.urls import url from django ...

  9. matplot画3d图像

    import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np fig = plt ...

  10. 【GStreamer开发】GStreamer基础教程08——pipeline的快捷访问

    目标 GStreamer建立的pipeline不需要完全关闭.有多种方法可以让数据在任何时候送到pipeline中或者从pipeline中取出.本教程会展示: 如何把外部数据送到pipeline中 如 ...