• 题目链接:

    https://www.luogu.org/problemnew/show/P3709

  • 思路:

    首先我是没读懂题目的,浏览了讨论区的dalao发现才知道就是求区间众数的出现次数。

    然后肯定是用莫队,具体怎么写莫队其他题解都写得很详细,这里不赘述.然后观察数据范围1e9肯定要离散化。

    但是题解里讲离散化的不多,我就讲一讲我自己瞎搞的一个离散化方法

    看到题解里其他dalao都是什么lower_bound或我看不懂的神仙操作。而蒟蒻我就瞎搞出了一个比较暴力的,也通俗易懂方法---开了两个map.

    第一个map al用来离散化,记录元素是否出现过.

    第二个map getrk顾名思义,用来离散化获取每个数的排名.

    dat[]用来记录原字符串,num[]用来记录去重后的数,即所有出现的元素

    读入字符串后将num[]从大到小排序,记录每一个出现元素的排名,当然就是用getrk

    接着就不管num[],我们遍历一遍获取原字符串中每个数的排名完成离散化.

    由于开了map,常数比较大,开了O2跑了2000多ms,但是能过就行了

  • 代码:

// luogu-judger-enable-o2
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <map>
#include <cmath>
using namespace std;
const int maxn=200005;
map <int,bool>al;
map <int,int>getrk;
struct Ask{
int l,r,id,x;
}ask[maxn];
int num[maxn],dat[maxn],rk[maxn];
int belong[maxn],block;
int N,n=0,m;
int a[maxn],cnt[maxn];
int ans[maxn],anss=0;
template<class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;
return ;
}
inline bool cmp0(const int&x,const int&y){
return x>y;
}
inline bool cmp2(const Ask &x,const Ask &y){
return belong[x.l]^belong[y.l]?belong[x.l]<belong[y.l]:belong[x.l]&1?x.r<y.r:x.r>y.r;
}
inline void init()
{
int x;
read(N),read(m);
block=N/sqrt(m*2/3);
n=0;
for(register int i=1;i<=N;i++){//N是原字符串长度
read(x);
dat[i]=x;
if(al[x]==0){//去重
num[++n]=x;//n是去重后num[]数组长度
al[x]=1;
}
belong[i]=(i-1)/block+1;
}
sort(num+1,num+1+n,cmp0);
for(register int i=1;i<=n;i++){
getrk[num[i]]=i;
// belong[i]=(i-1)/block+1;
}
for(register int i=1;i<=N;i++){
rk[i]=getrk[dat[i]];
}
//sort(num+1,num+1+n,cmp1);
for(register int i=1;i<=m;i++){
read(ask[i].l),read(ask[i].r);
ask[i].id=i;
}
sort(ask+1,ask+1+m,cmp2);
return;
}
inline void add(int x){
int now=rk[x];
if(anss==a[now])anss++;
cnt[a[now]]--;
a[now]++;
cnt[a[now]]++;
return;
}
inline void sub(int x){
int now=rk[x];
if(anss==a[now]&&cnt[a[now]]==1)anss--;
cnt[a[now]]--;
a[now]--;
cnt[a[now]]++;
return;
}
inline void solve()
{
int l=1,r=0,ll,rr;
cnt[0]=n;
for(register int i=1;i<=m;i++){
ll=ask[i].l,rr=ask[i].r;
while(r<rr)add(++r);
while(r>rr)sub(r),r--;
while(l<ll)sub(l),l++;
while(l>ll)add(--l);
ans[ask[i].id]=anss;
}
for(register int i=1;i<=m;i++){
printf("-%d\n",ans[i]);
}
return ;
}
int main()
{
init();
solve();
return 0;
}

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

  1. 【Luogu】P3709大爷的字符串题(莫队算法)

    题目链接 语文题啊…… 看题解发现是让求区间中最多的数的个数,于是果断理解了一会题解……莫队套上完事. sum[i]表示i这个数出现的次数,cnt[i]表示出现i次的数有几个,然后乱搞搞……就好了 # ...

  2. luogu P3709 大爷的字符串题

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    最近想要练习一下莫队(实在是掌握的太不熟练了啊.)这题一开始看到有点懵(题面杀),后来发现是要求众数的个数.乍一看好像很难的样子. 但仔细分析一下:首先往序列当中加入一个数,这个是很简单的,只需要维护 ...

  10. 并不对劲的p3709:大爷的字符串题

    题目大意 区间众数 题解 莫队 代码 #include<algorithm> #include<cmath> #include<cstdio> #include&l ...

随机推荐

  1. linux(redhat)安装jdk1.8

    第一步:下载Linux环境下的jdk1.8文件 我的Linux是32位的,因此我下载jdk-8u144-linux-i586.tar.gz文件. 下载链接地址:http://www.oracle.co ...

  2. 002-tomcat目录简介、应用部署【自动部署 ② 控制台部署 ③ 自定义部署】

    一.目录及功能 主目录下有bin,conf,lib,logs,temp,webapps,work 7个文件夹 1.1.bin目录[重要] bin目录主要是用来存放tomcat的命令,主要有两大类,一类 ...

  3. python同时执行两个函数

    使用两个线程同时执行两个函数, def fun1(): while True: time.sleep(2) print("fun1") def fun2(): while True ...

  4. 【JVM学习笔记】字节码文件结构实例

    上一篇笔记的内容大部分没有实际动手操作,因此决定完成这个完整的练习并记录下来. 另注,idea环境下有jclasslib插件用于更好的查看类似于javap结果的内容. 源代码如下: package c ...

  5. 数据库文件结构、sqlserver ON [PRIMARY]

    在sqlserver创建表的语句中,最后总来一句on[primary],这到底是什么意思? .联机丛书中CREATE TABLE的语法下似乎没有找到.最后终于发现,具体如下: 在CREATE TABL ...

  6. Asp.net Core深入一:数据库访问(Mysql为例)

    一.数据库概述 1.一个DBContext操纵一个数据库 2.DbContext下的一个DbSet<Model类>关联一个表,但是也可以只写一个表,DbContext可以关联其他的表. 3 ...

  7. libev 源码解析

    一  libev简介 libev是一个轻量级的事件通知库,具备支持多种事件通知能力,通过对libev的源码的阅读,可以清楚了解事件通知实现内部机制. 二 核心数据结构 在libev中关键的数据结构是, ...

  8. 【机器学习】ICA 原理以及相关概率论,信息论知识简介

    看完了sparse coding,开始看ICA模型,本来ng的教程上面就只有一个简短的介绍,怎奈自己有强迫症,爱钻牛角尖,于是乎就搜索了一些ICA的介绍文章(都是从百度文库中搜来的),看完之后感觉这个 ...

  9. 访问Nginx显示目录

    显示目录可以提供文件下载,方便文件共享时用到,mark一下. 1. 如何让nginx显示文件夹目录 vi /etc/nginx/conf.d/default.conf 添加如下内容: location ...

  10. JQuery自动填充控件:autocomplete(自己稍作了修改)

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...