LOJ #6285. 数列分块入门 9-分块(查询区间的最小众数)
#6285. 数列分块入门 9
题目描述
给出一个长为 nn 的数列,以及 nn 个操作,操作涉及询问区间的最小众数。
输入格式
第一行输入一个数字 nn。
第二行输入 nn 个数字,第 ii 个数字为 a_iai,以空格隔开。
接下来输入 nn 行询问,每行输入两个数字 ll、rr,以空格隔开。
表示查询位于 [l,r][l,r] 的数字的众数。
输出格式
对于每次询问,输出一行一个数字表示答案。
样例
样例输入
4
1 2 2 4
1 2
1 4
2 4
3 4
样例输出
1
2
2
2
数据范围与提示
对于 100\%100% 的数据,1 \leq n \leq 100000, -2^{31} \leq \mathrm{others}1≤n≤100000,−231≤others、\mathrm{ans} \leq 2^{31}-1ans≤231−1。
这道题,我交了82发,微笑:)
分块根号n是过不去的,是的,开80长度可以过,然后要打标记,查询的时候前一部分找过的,就打标记后一部分就不用再找了。
然后就是标记要用bool型,开int过不了,重新编号要用map,int过不了,还有就是主函数预处理的时候,块数是n/m+1,不再是m+1。
以上都是踩过的坑,灰常开心,写到自闭,最后看了别人的,发现长度开大了,改了就过了。
代码:
1 //#6285. 数列分块入门 9-查询区间的最小众数 2 #include<bits/stdc++.h> 3 using namespace std; 4 typedef long long ll; 5 const int maxn=1e5+10; 6 const int maxm=2e3+20; 7 8 int n,m,id=0; 9 int a[maxn],pos[maxn],val[maxn]; 10 int c[maxn],f[maxm][maxm]; 11 vector<int> vec[maxn]; 12 map<int,int> b; 13 bool vis[maxn]; 14 15 #define reads(n) FastIO::read(n) 16 namespace FastIO 17 { 18 const int SIZE = 1 << 16; 19 char buf[SIZE], obuf[SIZE], str[60]; 20 int bi = SIZE, bn = SIZE, opt; 21 int read(char *s) 22 { 23 while (bn) 24 { 25 for (; bi < bn && buf[bi] <= ' '; bi++); 26 if (bi < bn) 27 break; 28 bn = fread(buf, 1, SIZE, stdin); 29 bi = 0; 30 } 31 int sn = 0; 32 while (bn) 33 { 34 for (; bi < bn && buf[bi] > ' '; bi++) 35 s[sn++] = buf[bi]; 36 if (bi < bn) 37 break; 38 bn = fread(buf, 1, SIZE, stdin); 39 bi = 0; 40 } 41 s[sn] = 0; 42 return sn; 43 } 44 bool read(int& x) 45 { 46 int n = read(str), bf; 47 if (!n) 48 return 0; 49 int i = 0; 50 if (str[i] == '-') 51 bf = -1, i++; 52 else 53 bf = 1; 54 for (x = 0; i < n; i++) 55 x = x * 10 + str[i] - '0'; 56 if (bf < 0) 57 x = -x; 58 return 1; 59 } 60 }; 61 62 void init(int x) 63 { 64 // for(int i=0;i<=1e5+10;i++) 65 // c[i]=0; 66 int nummax=0,maxx=0; 67 memset(c,0,sizeof(c)); 68 for(int i=(x-1)*m+1;i<=n;i++){ 69 c[a[i]]++; 70 if(c[a[i]]>nummax||(c[a[i]]==nummax&&val[a[i]]<val[maxx])){ 71 nummax=c[a[i]]; 72 maxx=a[i]; 73 } 74 f[x][pos[i]]=maxx; 75 } 76 } 77 78 int length(int l,int r,int val) 79 { 80 return upper_bound(vec[val].begin(),vec[val].end(),r)-lower_bound(vec[val].begin(),vec[val].end(),l); 81 } 82 83 int query(int l,int r) 84 { 85 int maxx=f[pos[l]+1][pos[r]-1],nummax=0; 86 memset(vis,0,sizeof(vis)); 87 nummax=length(l,r,maxx); 88 vis[maxx]=1; 89 for(int i=l;i<=min(pos[l]*m,r);i++){ 90 if(vis[a[i]]==0){ 91 vis[a[i]]=1; 92 int ret=length(l,r,a[i]); 93 if(ret>nummax||(ret==nummax&&val[a[i]]<val[maxx])){ 94 nummax=ret; 95 maxx=a[i]; 96 } 97 } 98 } 99 if(pos[l]!=pos[r]){ 100 for(int i=(pos[r]-1)*m+1;i<=r;i++){ 101 if(vis[a[i]]==0){ 102 vis[a[i]]=1; 103 int ret=length(l,r,a[i]); 104 if(ret>nummax||(ret==nummax&&val[a[i]]<val[maxx])){ 105 nummax=ret; 106 maxx=a[i]; 107 } 108 } 109 } 110 } 111 return val[maxx]; 112 } 113 114 int main() 115 { 116 // reads(n); 117 scanf("%d",&n); 118 // m=sqrt(n); 119 m=80; 120 for(int i=1;i<=n;i++){ 121 // reads(a[i]); 122 scanf("%d",&a[i]); 123 pos[i]=(i-1)/m+1; 124 if(b[a[i]]==0){ 125 b[a[i]]=++id; 126 val[id]=a[i]; 127 } 128 a[i]=b[a[i]]; 129 vec[a[i]].push_back(i); 130 } 131 // for(int i=1;i<=pos[n];i++){132 for(int i=1;i<=n/m+1;i++){//块长为m,那么最多为n/m+1个块 133 init(i); 134 } 135 for(int i=1;i<=n;i++){ 136 int l,r; 137 // reads(l); 138 // reads(r); 139 scanf("%d%d",&l,&r); 140 printf("%d\n",query(l,r)); 141 } 142 }
完结,再见分块!
转载于:https://www.cnblogs.com/ZERO-/p/10525837.html
LOJ #6285. 数列分块入门 9-分块(查询区间的最小众数)相关推荐
- LibreOJ 6279 数列分块入门 3(分块+排序)
题解:自然是先分一波块,把同一个块中的所有数字压到一个vector中,将每一个vector进行排序.然后对于每一次区间加,不完整的块加好后暴力重构,完整的块直接修改标记.查询时不完整的块暴力找最接近x ...
- 分块的单点修改查询区间和_树状数组的区间修改与单点查询与区间查询
如何将普通树状数组升级 普通的单点修改单点查询就不讲了,从区间修改和单点查询讲起. 原来的值存在a[]里面,多建立个数组c1[],注意:c1[i]=a[i]-a[i-1]. 那么求a[i]的值的时候a ...
- 分块的单点修改查询区间和_模版 单点修改,区间查询
模板一:单点修改,区间求和 模板题:hdu1166 敌兵布阵 const int maxn=100010; int a[maxn],tree[4*maxn]; void pushup(int o){ ...
- 数列分块入门 (1 ~ 7)
分块 6277. 数列分块入门 1 分块思想 我们把每m个元素分成一块,所以我们总共的块数就是n/mn / mn/m块,一般情况下我们取m=nm = \sqrt{n}m=n.对于区间加操作,我们可以 ...
- 「分块系列」数列分块入门3 解题报告
数列分块入门3 题意概括 区间加法,区间求前驱. 写在前面 这题的方法与分块2方法极其类似,建议自行解决. 正题 和上一题类似,但是二分不是用来计数的,而是用来求小于c的最大值的.然后对于不完整快,将 ...
- 数列分块入门 9(LibreOj-6285)
[题目描述] 给出一个长为 n 的数列,以及 n 个操作,操作涉及询问区间的最小众数. [输入格式] 第一行输入一个数字 n. 第二行输入 n 个数字,第 i 个数字为 ai,以空格隔开. 接下来输入 ...
- LOJ #6279. 数列分块入门 3-分块(区间加法、查询区间内小于某个值x的前驱(比其小的最大元素))...
#6279. 数列分块入门 3 内存限制:256 MiB时间限制:1500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 3 题目描述 给出一 ...
- 【分块入门】LOJ 数列分块入门 1 - 9 (学习更新……)
dl题解 _「分块」数列分块入门1 – 9 by hzwer LOJ #6277. 数列分块入门 1 题意:给出一个长为n的数列,以及n个操作,操作涉及区间加法,单点查值. 时间限制:100ms 分块 ...
- LOJ 数列分块入门6
LOJ 数列分块入门6 题目: 题目 题解: 我都不懂这题为什么要用分块... ... 直接vector就好了... 但是如果有区间修改的话就不行了.所以这题是启示我们也可以动态分块.具体就是每次插入 ...
- LOJ——#6277. 数列分块入门 1
~~推荐播客~~ 「分块」数列分块入门1 – 9 by hzwer 浅谈基础根号算法--分块 博主蒟蒻,有缘人可直接观摩以上大佬的博客... #6277. 数列分块入门 1 题目大意: 给出一个长为 ...
最新文章
- 理解vuex -- vue的状态管理模式
- OpenGL的几何变换4之内观察全景图
- adobe audition cs6 能打开mpcm文件吗?_PR竟然有手机版的了?Adobe正式推出Premiere Rush版(内含安装包)!...
- 京瓷1020怎么打印自检页_[建筑]喷墨打印机如何打印自检页 详细
- 汇编语言(十五)之找出两个数组中的相同元素
- MYSQL 查看表上索引的 1 方法
- instanceof 的运用
- jxl读取html格式excel,基于Java+Selenium的WebUI自动化测试框架(十)-----读取Excel文件(JXL)...
- 架构师一般做到多少岁_《迷茫中的我们该如何突破瓶颈——成长为一名架构师》...
- 迅雷禁止更新设置方法【禁止升级】【禁止更新】
- Visual Studio 2017 Enterprise绿色精简版介绍
- 百面机器学习 #2 模型评估:0102 精确率与召回率,假阳性与真阳性率,PR曲线和ROC曲线
- 【Linux】必须掌握的Linux常见指令分类讲解
- 音视频开发——概述(含TUTK demo iOS)
- 【RC延迟电路与快速泄放电路】 multisim 14.0仿真 RC延迟电路与快速泄放电路
- ARP攻击原理与实践
- 学术期刊论文写作和研读相关体系
- 【翻译】Mathematical Analysis of Algorithms
- Internet Download Manager v6.36 Build 3 Final 注册版-IDM下载工具
- Macbook上怎么隐藏文件和文件夹
热门文章
- MongoDB 学习笔记之 手动预先分片
- Ubuntu系统多屏幕时 触摸屏如何分屏定位
- freeswitch 电话会议
- js实现快速排序(in-place)简述
- !HDU 1078 FatMouse and Cheese-dp-(记忆化搜索)
- JavaScript中常见的字符串操作函数及用法
- SSL ×××和IPSec的主要区别
- 高效使用电脑,Fence和Direct Folder
- 金蝶ERP实现产品入库及委外加工冲减生产现场虚仓毛坯数(修正版07-05-10)
- Spring Boot + Prometheus + Grafana 打造可视化监控,一目了然!