[Luogu 3709]大爷的字符串题

题目描述:

出题人语文不好系列。
查询 l - r 中众数出现次数的负值

题目分析:

莫队。(不想写分块qwq
维护每个数字出现的次数以及每个出现次数数字的个数
不搞离散化 RE没商量

题目链接:

Luogu 3709

Ac 代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
const int maxm=210000; 
int sum[maxm],cnt[maxm],num[maxm];
int pos[maxm];
int hash[maxm];
int ans[maxm];
struct ask{
    int l,r;
    int id;
}q[maxm];
inline bool comp(ask x,ask y){return pos[x.l]==pos[y.l]?x.r<y.r:x.l<y.l;}
int block_num,block_len;
int n,m,Ans;
int update(int w,bool f)
{
    if(f)
    {
        cnt[sum[w]]--;
        cnt[++sum[w]]++;
        if(cnt[Ans+1]) Ans++;
    }
    else
    {
        cnt[sum[w]]--;
        cnt[--sum[w]]++;
        while(!cnt[Ans]) Ans--;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    block_len=std::sqrt(n);
    block_num=(n/block_len+((n%block_len)!=0));
    for(int i=1;i<=n;i++)
     pos[i]=(i-1)/block_len+1;
    for(int i=1;i<=n;i++)
     scanf("%d",&num[i]),hash[i]=num[i];
    std::sort(hash+1,hash+n+1);
    int t=std::unique(hash+1,hash+n+1)-hash-1;
    for(int i=1;i<=n;i++)
     num[i]=std::lower_bound(hash+1,hash+t+1,num[i])-hash;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
        if(q[i].l>q[i].r) std::swap(q[i].l,q[i].r);
    }

    std::sort(q+1,q+m+1,comp);
    int l=1,r=0;
    cnt[0]=t;
    for(int i=1;i<=m;i++)
    {
        while(l>q[i].l) update(num[--l],1);
        while(l<q[i].l) update(num[l++],0);
        while(r<q[i].r) update(num[++r],1);
        while(r>q[i].r) update(num[r--],0);
        ans[q[i].id]=Ans;
    }
    for(int i=1;i<=m;i++)
     printf("%d\n",-ans[i]);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值