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 ...
随机推荐
- 转 Spring源码剖析——核心IOC容器原理
Spring源码剖析——核心IOC容器原理 2016年08月05日 15:06:16 阅读数:8312 标签: spring源码ioc编程bean 更多 个人分类: Java https://blog ...
- 02Vs2013常用路径配置
1.设置头文件路径 项目 -> xxx属性页 -> 配置属性 -> C/C++ -> 常规 -> 附加包含目录. 2.包含 x.lib 库路径 项目 -> xxx属 ...
- centos7.4进入单用户模式
centos7.4进入单用户模式 1 - 在启动grub菜单,选择编辑选项启动 2 - 按键盘e键,来进入编辑界面 3 - 找到Linux 16的那一行,将ro改为rw init=/sysroot/b ...
- w3resource_MySQL练习:Basic_select_statement
w3resource_MySQL练习题:Basic_select_statement 1. Write a query to display the names (first_name, last_n ...
- Latex:插入伪代码
*本文属于转载. *转载链接:https://blog.csdn.net/lwb102063/article/details/53046265 目录 clrscode algorithm algori ...
- debian7不能apt安装emacs24
维护者在主页上 http://emacs.naquadah.org/ 提到: These packages are not maintained anymore I don't use these p ...
- Linux学习-灾难复原的考虑
硬件损毁,且具有完整备份的数据时 由于是硬件损毁,所以我们不需要考虑系统软件的不稳定问题,所以可以直接将完整的系统复原回去 即可. 由于软件的问题产生的被攻破资安事件 由于系统的损毁是因为被攻击,此时 ...
- CodeForces 570E DP Pig and Palindromes
题意:给出一个n行m列的字符矩阵,从左上角走到右下角,每次只能往右或者往下走,求一共有多少种走法能得到回文串. 分析: 可以从两头开始考虑,每次只走一样字符的格子,这样得到的两个字符串拼起来之后就是一 ...
- linux 下java jar包的方法
test.java 和 example.jar 在同一目录:并且test.java引用了example.jar 首先编译test.java: javac -cp example.jar test. ...
- poj3255 Roadblocks 次短路
Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10098 Accepted: 3620 Descr ...