大爷的字符串题

莫队水毒瘤题

出题人语文水平极高,题意理解一下

就是求区间众数出现次数(什么毒瘤题目)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5211314;
int a[maxn], pos[maxn], s[maxn],d[maxn];
int cnt[maxn],ans[maxn],lx,n,m;
int re(){
    int x=0,w=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)w=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar();
    return x*w;
}
struct query{
    int l,r,id;
}q[maxn];
bool cmp(query a,query b){
    return (pos[a.l]==pos[b.l])?((pos[a.l]&1)?a.r<b.r:a.r>b.r):pos[a.l]<pos[b.l];
}
inline void add(int x){
    s[cnt[a[x]]++]--;s[cnt[a[x]]]++;lx=max(lx,cnt[a[x]]);
}
inline void del(int x){
    s[cnt[a[x]]]--;if(cnt[a[x]]==lx&&!s[lx])lx--;s[--cnt[a[x]]]++;
}
int main() {
    n=re(),m=re();
    int size=sqrt(n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        d[i]=a[i];
        pos[i] = (i - 1) / size + 1;
    }
    sort(d+1,d+n+1);int len=unique(d+1,d+n+1)-d-1;
    for(int i=1;i<=n;i++)
        a[i]=lower_bound(d+1,d+len+1,a[i])-d;
    for(int i=1;i<=m;i++){
        q[i].l=re(),q[i].r=re();
        q[i].id=i;
    }
    sort(q+1,q+m+1,cmp);
    int r=0,l=1;
    for (int i = 1; i <= m; i++) {
        while(r<q[i].r)add(++r);
        while(r>q[i].r)del(r--);
        while(l<q[i].l)del(l++);
        while(l>q[i].l)add(--l);
        ans[q[i].id]=lx;
    }
    for(int i=1;i<=m;i++)printf("%d\n",-ans[i]);
}

原文地址:https://www.cnblogs.com/wilxx/p/11697524.html

时间: 2024-10-09 03:59:13

大爷的字符串题的相关文章

luogu P3709 大爷的字符串题

二次联通门 : luogu P3709 大爷的字符串题 /* luogu P3709 大爷的字符串题 莫队 看了半天题目 + 题解 才弄懂了要求什么... 维护两个数组 一个记录数字i出现了几次 一个记录出现了i次的有几个数.. */ #include <algorithm> #include <cstdlib> #include <cstdio> #include <cmath> #define Max 200090 void read (int &

大爷的字符串题 莫队

大爷的字符串题 莫队 首先这不是一道字符串题.需要仔细研究题的性质,我们会发现答案即为区间众数的个数,因为我们可以将区间分为众数个递增数列,这样为最优. 所以问题转换为求区间众数个数.使用莫队. #include <cstdio> #include <algorithm> #include <cmath> #define MAXN 400020 using namespace std; int ans,a[MAXN],cnt[MAXN],sum[MAXN]; inlin

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

题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区间中随机拿出一个字符x,然后把x从这个区间中删除,你要维护一个集合S 如果S为空,你rp减1 如果S中有一个元素不小于x,则你rp减1,清空S 之后将x插入S 由于你是大爷,平时做过的题考试都会考到,所以每次询问你搞完这段区间的字符之后最多还有多少rp?rp初始为0 询问之间不互相影响~ 输入输出格

洛谷 P3709 大爷的字符串题

https://www.luogu.org/problem/show?pid=3709 题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区间中随机拿出一个字符x,然后把x从这个区间中删除,你要维护一个集合S 如果S为空,你rp减1 如果S中有一个元素不小于x,则你rp减1,清空S 之后将x插入S 由于你是大爷,平时做过的题考试都会考到,所以每次询问

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

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

[P3709] 大爷的字符串题

Link: P3709 传送门 Solution: lxl出的语文题 其实转化一下就是求将当前区间最少拆分成多少个严格单调上升序列(可不连续) 再转化一下就是求区间内的众数个数 本来求众数的套路是主席树+二分 但此题不要求在线,用莫队同时维护$i$的出现次数$cnt[i]$和出现次数为$i$的数的个数$sum[i]$ 这样常规套路更新结果就好了 Code: #include <bits/stdc++.h> using namespace std; const int MAXN=5e5+10;

luogu P3709大爷的字符串题

lxl出的又一道毒瘤题,题目本身让人读不懂,然而实际上题面用一句话就可以总结: 给你n个数,m次询问区间[l,r]中众数的出现次数 然后就用普通的莫队就好啦~~(数据也没有那么毒瘤) #include<algorithm> #include<cmath> #include<cstdio> using namespace std; const int maxn = 200200; int pos[maxn], num[maxn]; int ans[maxn]; int f

字符串题模板集合

后缀数组 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <string.h> #include <vector> #include <limits> #include <set> #include <map> using namespace std; #define S

字符串题表

已完成bzoj1559 ** ac+jvchengbzoj1195:[HNOI2006]最短母串 ** ac+jvchengbzoj1692 * sabzoj1031 * sabzoj3796 ** sa+kmpbzoj3230:相似子串 ** sa+stbzoj4698 *** sabzoj2160:拉拉队排练 * manacherbzoj3790 * manacher+tanxinbzoj2565:最长双回文串 * manacher+luangaobzoj1414:[ZJOI2009]对称的