最近想要练习一下莫队(实在是掌握的太不熟练了啊。)这题一开始看到有点懵(题面杀),后来发现是要求众数的个数。乍一看好像很难的样子。

  但仔细分析一下:首先往序列当中加入一个数,这个是很简单的,只需要维护一个 \(cnt[k]\) 表示 \(k\) 数字出现的次数,看看是否超过了当前维护的最大值即可。难在如何从区间中删除一个数:要注意到莫队所具有的一个独特性质即每一次的转移只在相邻的两格之间发生。这就大大的简化了问题:分成两个部分来考虑,即1.当前删去的数是众数 / 2. 当前删去的数不是众数。我们再维护一个数组 \(num[k]\) 表示在当前区间中出现了 \(k\) 次的数一共有多少个。如果删去的是众数,则查看一下是否还有别的众数,否则答案-1;不是众数,更新一下两个数组即可。

#include <bits/stdc++.h>
using namespace std;
#define maxn 400000
int n, m, k, B = , tot;
int Ans[maxn], cnt[maxn], ans;
int b[maxn], a[maxn], num[maxn];
map <int, int> Map; struct node
{
int l, r, id, bel;
node(int ll = , int rr = , int idx = ) { l = ll, r = rr, id = idx; bel = ll / B + ; }
friend bool operator <(const node& a, const node& b)
{
if(a.bel != b.bel) return a.bel < b.bel;
else return a.r < b.r;
}
}Q[maxn]; int read()
{
int x = , k = ;
char c;
c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} void Minus(int k)
{
if(ans == cnt[a[k]])
if(num[cnt[a[k]]] == ) ans = cnt[a[k]] - ;
num[cnt[a[k]]] --, num[-- cnt[a[k]]] ++;
} void Add(int k)
{
if(ans == cnt[a[k]]) ans = cnt[a[k]] + ;
if(cnt[a[k]] + > ans) ans = cnt[a[k]] + ;
num[cnt[a[k]]] --, num[++ cnt[a[k]]] ++;
} signed main()
{
n = read(), m = read(); B = sqrt(n);
for(int i = ; i <= n; i ++) b[i] = a[i] = read();
sort(b + , b + + n);
for(int i = ; i <= n; i ++)
if(b[i] != b[i - ] || i == ) Map[b[i]] = ++ tot;
for(int i = ; i <= n; i ++)
a[i] = Map[a[i]];
for(int i = ; i <= m; i ++)
{
int l = read(), r = read();
Q[i] = node(l, r, i);
}
sort(Q + , Q + + m);
int ll = , rr = ; ans = , cnt[a[]] = , num[] = ;
for(int i = ; i <= m; i ++)
{
if(Q[i].l <= rr)
{
while(ll < Q[i].l) Minus(ll), ll ++;
while(ll > Q[i].l) ll --, Add(ll);
while(rr > Q[i].r) Minus(rr), rr --;
while(rr < Q[i].r) rr ++, Add(rr);
}
else
{
while(rr > Q[i].r) Minus(rr), rr --;
while(rr < Q[i].r) rr ++, Add(rr);
while(ll < Q[i].l) Minus(ll), ll ++;
while(ll > Q[i].l) ll --, Add(ll);
}
Ans[Q[i].id] = ans;
}
for(int i = ; i <= m; i ++) printf("-%d\n", Ans[i]);
return ;
}

【题解】洛谷P3709大爷的字符串题的更多相关文章

  1. 洛谷P3709 大爷的字符串题(莫队)

    题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区 ...

  2. 洛谷 P3709 大爷的字符串题

    https://www.luogu.org/problem/show?pid=3709 题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个 ...

  3. [洛谷P3709]大爷的字符串题

    题目传送门 不用管它随机什么的,就用贪心的思想去想, 会发现这道题的实质是:求查询区间众数出现次数. 莫队即可解决. 注意字符集1e9,要离散化处理. #include <bits/stdc++ ...

  4. 洛谷P3709 大爷的字符串

    题意:多次求区间众数的出现次数. 解: 这题居然可以莫队...... 首先开个桶.然后还要开个数组,cnt[i]表示出现i次的数有多少个. 然后就可以O(1)修改了. #include <cst ...

  5. luogu P3709 大爷的字符串题

    二次联通门 : luogu P3709 大爷的字符串题 /* luogu P3709 大爷的字符串题 莫队 看了半天题目 + 题解 才弄懂了要求什么... 维护两个数组 一个记录数字i出现了几次 一个 ...

  6. P3709 大爷的字符串题 (莫队)

    题目 P3709 大爷的字符串题 题意:求\([l,r]\)中众数的个数. 解析 维护两个数组: \(cnt[x]\),数\(x\)出现的次数. \(sum[x]\),出现次数为\(x\)的数的个数. ...

  7. P3709 大爷的字符串题(莫队+结论)

    题目 P3709 大爷的字符串题 做法 有一个显然的结论:一段区间里最小答案为众数的个数 用莫队来离线求众数 \(tmp_i\)表示出现\(i\)次的数的个数,\(num_i\)表示\(i\)出现的次 ...

  8. P3709 大爷的字符串题(50分)

    题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区 ...

  9. 【luogu P3709 大爷的字符串题】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3709 离散化+区间众数..? #include <iostream> #include < ...

随机推荐

  1. maven私有库搭建

    一.在企业中基本上都会有自己的maven私有库,主要的目的就是方便依赖包的下载.如果采用远程的方式来实现的话,很多时候会考虑网速问题.如果自己活着公司搭建的私有库,这一样在使用上面会效率更高. 二.私 ...

  2. hdu2899Strange fuction(解方程+二分)

    Strange fuction Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  3. 2019年1月23日,好像是这个日子,RF发布了 1.7.3.1 支持python3.6以上了,安装成功。

    安装步骤:(win10 家庭版 64) 1.安装Python3.7.2,记得勾选添加Path 2.pip install robotframework 3.pip install wxPython 4 ...

  4. C 数数位 while循环

    #include <stdio.h> int main(int argc, char **argv) { //定义两个变量  x n 把n初始化 int x; int n=0; //输入x ...

  5. 1 wait notify

    wait/notify: wait()使线程停止,notify使wait状态的线程继续执行. wait()是Object类的方法,该方法用来将线程置入“预执行队列”,并在wait()方法处停止执行,直 ...

  6. 棋盘问题:dfs

    Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子 ...

  7. Python3 Tkinter-Label

    1.创建 from tkinter import * root=Tk() root.title('Hello tkinter!') root.mainloop() 2.使用内置位图 from tkin ...

  8. java DTO 转 POJO

    如果这两个类的要转化的属性其属性名不一样的话,那只能用get和set方法赋值 如果你的两个类要转化的属性名都一样,那可以用org.springframework.beans.BeanUtils这个类来 ...

  9. vue.js学习之 打包为生产环境后,页面为白色

    vue.js学习之 打包为生产环境后,页面为白色 一:配置问题 当我们将项目打包为生产环境后,在dist文件夹下打开index.html,会发现页面为白色. 1:打开config>index.j ...

  10. iOS开发应用程序生命周期

    各个程序运行状态时代理的回调: - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSD ...