「ZJOI2022」众数

d1t2

大家好,我不会根号实锤了。

因为跟众数有关并且看起来就要对所有种类的数求一个答案,可以直接考虑根号算法。

没有什么好的分块思路,不妨根号分治。按数的种类处理,按大小分治:

  • 出现次数大于 n:这种数最多 O(n) 个,颜色是 O(n) 个的,每种颜色处理一下就是 O(nn) 的;
  • 出现次数小于等于 n:记其出现位置为 p0=0,p1,p2,,pk,pk+1=n+1,那么改 (pi,pj) 对这种数来说最优,枚举 i,j,总时间复杂度分析后可知是 O(nn) 的。

然后先处理出现次数大于 n 的。假设这种颜色为 p,我们试图把 p 改成 q 更新 q,或是把 q 改成 p 更新 p。维护 p 出现次数的前缀和直接处理,这是简单的。

然后再处理出现次数不大于 n 的数。注意到一点是在上面的处理中我们处理了一个出现次数大于 n 的数 p 改成出现次数不大于 n 的数 q,所以在这里只考虑两个数出现次数都不大于 n 的。

那么相当于做 O(nn) 次区间众数。但是有一点是每个数出现次数都是不大于 O(n) 的。那么记 si[i,n] 的众数出现次数,容易发现 si=O(nn) 的,其支持暴力维护。

暴力枚举 [l,r]。现在已经枚举了 r,再枚举 l。容易发现我们可以根据上面分讨得出的一个简单小结论优化枚举过程,也就是保证 l1r 颜色一样,或者 l=1 即可。显然 sisi1,我们可以暴力更新 [i,r] 的区间众数,更新次数不大于 O(nn),可以保证复杂度。

代码比题解清楚。

void SmChunk()
{
    for(int i=1;i<=n;++i)   sum[i]=0;
    for(int i=1;i<=n;++i)
    {
        if(app[a[i]]<=Sqr)
        {
            int p=lower_bound(Pos[a[i]].begin(),Pos[a[i]].end(),i)-Pos[a[i]].begin();
            for(int j=p;~j;--j)
            {
                int l=j?Pos[a[i]][j-1]+1:1,r=Pos[a[i]][j];
                maxn[a[i]]=max(maxn[a[i]],sum[l]-(p-j));
                while(l<=r && sum[r]<p-j+1) sum[r--]=p-j+1;
            }
        }
    }
}
void Solve()
{
    n=read();
    for(int i=1;i<=n;++i)   a[i]=b[i]=read();
    sort(b+1,b+1+n);
    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<=len;++i) app[i]=0,Pos[i].clear(),maxn[i]=0;
    for(int i=1;i<=n;++i)   ++app[a[i]],Pos[a[i]].push_back(i);
    for(int p=1;p<=len;++p)
    {
        if(app[p]>Sqr)
        {
            for(int i=1;i<=n;++i)   sum[i]=sum[i-1]+int(a[i]==p);
            for(int q=1;q<=len;++q)
            {
                int N=app[q],l,s;
                l=s=0;
                for(int i=0;i<N;++i)
                {
                    int r=Pos[q][i];
                    s=max(0,s-(sum[r]-sum[l]))+1;
                    maxn[p]=max(maxn[p],s);
                    l=r;
                }
                l=s=0;
                for(int i=0;i<N;++i)
                {
                    int r=Pos[q][i];
                    s=max(0,s)+sum[r]-sum[l];
                    maxn[q]=max(maxn[q],s--);
                    l=r;
                }
            }
        }
    }
    SmChunk();
    reverse(a+1,a+1+n);
    for(int i=1;i<=len;++i)
    {
        reverse(Pos[i].begin(),Pos[i].end());
        for(auto &st:Pos[i])    st=n-st+1;
    }
    SmChunk();
    for(int i=1;i<=len;++i) maxn[i]+=app[i];
    int ans=0;
    for(int i=1;i<=len;++i) ans=max(ans,maxn[i]);
    write(ans),puts("");
    for(int i=1;i<=len;++i) if(maxn[i]==ans)    write(b[i]),puts("");
}
posted @   SyadouHayami  阅读(92)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

My Castle Town.

点击右上角即可分享
微信分享提示