博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

洛谷 P3709 大爷的字符串题 解题报告

题目描述

给你一个字符串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最少,那么就是求最少可以将数列分成几段单调上升子序列。

单调上升子序列的个数,就是最后的答案。

如果所有数字均不重复,那么答案等于1

有一个数字重复,那么就是2

因此,答案就等于众数的出现次数。

因为ai最大为109,所以要先对a数组离散化。(因为只是求众数出现次数,故离散化后无任何影响)

统计一个数字出现次数cnt,再统计一下这个数字出现次数的出现次数(形容的比较抽象,看下面的解释/代码)。

  • add操作

  只要这个数字出现次数等于当前ans,那么ans++。

  • del操作

  当前数字出现次数等于ans,并且这个数字的数量的出现次数为1,即没有别的数字出现次数等于ans,那么ans--


代码如下:

#include <bits/stdc++.h>
using namespace std;

inline void read(int &a) {a=0;int b=1,c=getchar(); while(c!='-'&&(c>'9'||c<'0')) c=getchar(); if(c=='-') b=-1,c=getchar(); while(c>='0'&&c<='9') a=(a<<3)+(a<<1)+c-48,c=getchar(); a*=b; }

const int N=2e5+5;
int n,m,a[N],block,b[N],cnt[N],rec[N],ans,zs[N];
struct sq
{
    int l,r,id;
}q[N];

inline bool cmp(sq a,sq b)
{
    return (a.r/block)==(b.r/block)?a.l<b.l:a.r<b.r;
}

inline void add(int x)
{
    if(cnt[a[x]]==ans) ++ans;
    zs[cnt[a[x]]]--;
    zs[++cnt[a[x]]]++;
}

inline void del(int x)
{
    if(ans==cnt[a[x]]&&zs[cnt[a[x]]]==1) --ans;
    zs[cnt[a[x]]]--;
    zs[--cnt[a[x]]]++;
}

int main()
{
    read(n);read(m);block=sqrt(n);
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
        b[i]=a[i];
    }
    sort(b+1,b+1+n);
    int len=unique(b+1,b+1+n)-b-1;
    for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+len,a[i])-b;
    for(int i=1;i<=m;i++) {read(q[i].l);read(q[i].r); q[i].id=i; }
    sort(q+1,q+1+m,cmp);
    int l=1,r=0;
    for(int i=1,ql,qr,qi;i<=m;i++)
    {
        ql=q[i].l,qr=q[i].r,qi=q[i].id;
        while(l<ql) del(l++);
        while(l>ql) add(--l);
        while(r<qr) add(++r);
        while(r>qr) del(r--);
        rec[qi]=ans;
    }
    for(int i=1;i<=m;i++) cout<<-rec[i]<<'\n';
    return 0;
}
View Code

 

posted @ 2018-12-08 19:58  楚泫  阅读(222)  评论(0编辑  收藏  举报