zoukankan      html  css  js  c++  java
  • P3709 大爷的字符串题 (莫队)

    传送门

    首先这个题面弯弯绕绕就读不懂

    瞟了一眼题解,就是求一个区间里面的众数的出现次数。

    因为这个区间不更改,可离线,那就上莫队就行了

    莫队求众数,记 x 出现次数 cnt[x],记出现次数为 n 的数的个数为 num[n],当前众数的次数为 now

    添加的话,直接修改 cnt 和 num,用 cnt 去更新 now

    删除的话,如果这时 num[cnt[x]] == 1 并且 cnt[x] == now,那么删除 x 之后,就没有 cnt == now 的数了,now--。也可以像代码里那样处理

    #include <iostream>
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <algorithm>
    #define MAXN 200010
    using namespace std;
    int n,m,a[MAXN],b[MAXN],pos[MAXN],ans[MAXN],cnt[MAXN],num[MAXN],now;
    
    struct Ques{
        int l,r,id;
    }q[MAXN];
    
    bool cmp(Ques x,Ques y){return pos[x.l]<pos[y.l]||pos[x.l]==pos[y.l]&&x.r<y.r;}
    
    void add(int x){
        num[cnt[x]]--;
        num[++cnt[x]]++;
        now=max(now,cnt[x]);
    }
    
    void del(int x){
        num[cnt[x]]--;
        if(cnt[x]==now&&!num[cnt[x]]) now--;
        num[--cnt[x]]++;
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        int sz=sqrt(n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i],pos[i]=i/sz;
        sort(b+1,b+n+1);
        int tot=unique(b+1,b+n+1)-b-1;
        for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
        for(int i=1;i<=m;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
        sort(q+1,q+m+1,cmp);
        int L=0,R=0;
        num[0]=tot;
        for(int i=1;i<=m;i++){
            while(R<q[i].r) add(a[++R]);
            while(R>q[i].r) del(a[R--]);
            while(L>q[i].l) add(a[--L]);
            while(L<q[i].l) del(a[L++]);
            ans[q[i].id]=-now;
        }
        for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    Hibernate----面试题
    Java框架部分---面试题
    面试题---多线程
    swap分区
    Linux之格式化与挂载
    Linux下的GPT分区
    Linux下的MBR分区
    vim基础初步
    管道符,通配符以及其他特殊符号
    shell基础之脚本执行,命令别名以及快捷键等
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/11741677.html
Copyright © 2011-2022 走看看