luogu 3709 大爷的字符串题 构造 莫队 区间众数
题目链接
题目描述
给你一个字符串a,每次询问一段区间的贡献
贡献定义:
每次从这个区间中随机拿出一个字符\(x\),然后把\(x\)从这个区间中删除,你要维护一个集合S
如果\(S\)为空,你\(rp\)减\(1\)
如果S中有一个元素不小于\(x\),则你\(rp\)减\(1\),清空\(S\)
之后将\(x\)插入\(S\)
由于你是大爷,平时做过的题考试都会考到,所以每次询问你搞完这段区间的字符之后最多还有多少\(rp\)?\(rp\)初始为\(0\)
询问之间不互相影响~
输入输出格式
输入格式:
第一行两个数\(n\),\(m\),表示字符串长度与询问次数
之后一行\(n\)个数,表示字符串
由于你是大爷,所以字符集\(1e9\)
之后\(m\)行每行两个数,表示询问的左右区间
输出格式:
\(m\)行,每行一个数表示答案
输入输出样例
输入样例#1:
3 3
3 3 3
3 3
3 3
3 3
输出样例#1:
-1
-1
-1
思路
构造
要使得扣除尽量少的\(rp\),就要使得每次操作插入的数大于原先集合中已有的数字,即保持集合的严格单调性。到万不得已的时候再重新开始。
共需重新开始的次数为出现最多的一个数出现的个数,即众数的出现次数。
故题意就是给一个序列,每次询问一个区间,问这个区间里的众数的出现次数。
莫队算法
可用莫队算法离线处理所有询问。
维护众数的出现次数:用\(cnt[i]\)维护数字\(i\)的出现次数,用\(num[i]\)维护出现了\(i\)次的数字有多少个,因此,最大的不为\(0\)的\(num[\ ]\)的下标即为众数的出现次数。
注意点
读入初始数据之后就要进行离散化。如果用\(map\)存,每次操作的时候都进行映射,这样时间代价太大。
Code
/*
下面是50分代码↓↓↓
基本上参考着Candy?大佬的从头到尾改了一遍后来又厚颜无耻地交了一发大佬的代码都还是有5组一直T十分困惑...。
就姑且先50分着吧。还是学到了不少的,比如莫队的优美写法、\(cnt\)和\(num\)的妙招、先离散化而不是用\(map\)瞎搞。
*/
#include <bits/stdc++.h>
#define maxn 200010
using namespace std;
typedef long long LL;
int a[maxn], ans[maxn], cnt[maxn], mp[maxn], num[maxn], now, block[maxn];
struct node {
int l, r, id;
}q[maxn];
inline LL read(){
char c=getchar(); LL x=0,f=1;
while(c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
return x*f;
}
bool cmp(node u, node v) {
return block[u.l] < block[v.l] || (block[u.l] == block[v.l] && block[u.r] < block[v.r]);
}
void add(int i) {
--num[cnt[a[i]]], ++num[++cnt[a[i]]];
while (num[now+1]) ++now;
}
void del(int i) {
--num[cnt[a[i]]], ++num[--cnt[a[i]]];
while (!num[now]) --now;
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
int grp = sqrt(n);
for (int i = 1; i <= n; ++i) a[i] = mp[i] = read(), block[i] = (i-1) / grp;
sort(mp+1, mp+1+n);
int nn = unique(mp+1, mp+1+n) - (mp+1);
for (int i = 1; i <= n; ++i) a[i] = lower_bound(mp+1, mp+1+nn, a[i]) - mp;
for (int i = 0; i < m; ++i) q[i].l = read(), q[i].r = read(), q[i].id = i;
sort(q, q+m, cmp);
int l = 0, r = 0;
for (int i = 0; i < m; ++i) {
while (q[i].l < l) add(--l);
while (q[i].l > l) del(l++);
while (q[i].r < r) del(r--);
while (q[i].r > r) add(++r);
ans[q[i].id] = now;
}
for (int i = 0; i < m; ++i) printf("%d\n", -ans[i]);
return 0;
}
luogu 3709 大爷的字符串题 构造 莫队 区间众数的更多相关文章
- 【Luogu】P3709大爷的字符串题(莫队算法)
题目链接 语文题啊…… 看题解发现是让求区间中最多的数的个数,于是果断理解了一会题解……莫队套上完事. sum[i]表示i这个数出现的次数,cnt[i]表示出现i次的数有几个,然后乱搞搞……就好了 # ...
- [ Luogu 3709 ] 大爷的字符串题
\(\\\) Description 原题题面太过混乱出题人语文凉凉 给出一个长为 \(n\) 的数列 \(A\) ,多次询问: 对于一个区间 \([L_i,R_i]\),把区间内的所有数最少划分成多 ...
- 洛谷P3709 大爷的字符串题(莫队)
题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区 ...
- P3709 大爷的字符串题 脑子+莫队
简化题意:区间众数出现次数??? 为什么?原因是,贪心的想,我们要划分成尽量少的严格递增序列,这样rp掉的最少. 设区间众数出现次数为 \(x\) ,那我们至少要分成 \(x\) 段严格上升序列. # ...
- luogu P3709 大爷的字符串题
二次联通门 : luogu P3709 大爷的字符串题 /* luogu P3709 大爷的字符串题 莫队 看了半天题目 + 题解 才弄懂了要求什么... 维护两个数组 一个记录数字i出现了几次 一个 ...
- 【luogu P3709 大爷的字符串题】 题解
题目链接:https://www.luogu.org/problemnew/show/P3709 离散化+区间众数..? #include <iostream> #include < ...
- P3709 大爷的字符串题(莫队+结论)
题目 P3709 大爷的字符串题 做法 有一个显然的结论:一段区间里最小答案为众数的个数 用莫队来离线求众数 \(tmp_i\)表示出现\(i\)次的数的个数,\(num_i\)表示\(i\)出现的次 ...
- P3709 大爷的字符串题 (莫队)
题目 P3709 大爷的字符串题 题意:求\([l,r]\)中众数的个数. 解析 维护两个数组: \(cnt[x]\),数\(x\)出现的次数. \(sum[x]\),出现次数为\(x\)的数的个数. ...
- AC日记——大爷的字符串题 洛谷 P3709
大爷的字符串题 思路: 莫队,需开O2,不开50: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 20000 ...
随机推荐
- c++调用系统关机命令 c++调用暂停命令
#include<stdlib.h> int main() { //调用系统dos命令 system("shutdown -s -t 120"); ; } system ...
- drawRect - 谈画图功能的内存优化
作者介绍 作者:毕洪博 ( @毕洪博 ),iOS 开发者,pop Art 追随者.现在正在鼓捣 AVFoundation,博客 bihongbo.com, 欢迎大家找我讨论技术. 作者已将本文在微信公 ...
- ios 设计模式总结
设计模式:备注:消息传递模型(Message Passing)是Objective-C语言的核心机制.在Objective-C中,没有方法调用这种说法,只有消息传递.在C++或Java中调用某个类的方 ...
- d3网址
官网: http://d3js.com D3创始人 http://bost.ocks.org.mike 教程: http://www.dashingd3js.com/table-of-contents ...
- echarts事件中获取当前实例
直接使用this即可
- 使用filter函数筛选出素数
function getPrimeNumber(arr) { return arr.filter(function (number) { if (typeof number !== 'number' ...
- CentOS7.2下Hadoop2.7.2的集群搭建
1.基本环境: 操作系统: Centos 7.2.1511 三台虚机: 192.168.163.224 master 192.168.163.225 node1 192.168.163.226 ...
- 给vagrant中的precise64升级VBoxGuestAdditions
位置:/usr/share/virtualbox/VBoxGuestAdditions.iso 在host(ubuntu 12.04 64)中: 查看虚拟机的名字:jb@H38:~/vm/vagran ...
- Selenium WebDriver-打开3个网址截图,文件夹用年月日命名,图片用当前时分秒命名
import os import os.path import time from selenium import webdriver urls=["http://www.baidu.com ...
- adb devices 找不到夜神模拟器解决方法
先打开命令行窗口,输入adb devices,查看连接信息,大致意思是sdk的adb版本与夜神的adb版本不一致,导致. C:\Users\cz9025>adb devices List of ...