Luogu4168 [Violet]蒲公英

Posted wifimonster

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu4168 [Violet]蒲公英相关的知识,希望对你有一定的参考价值。

题面:https://www.luogu.org/problemnew/show/P4168

首先离散化;

考虑分块,记录信息:

cnt[i][j]表示前i个块元素j出现的次数 

f[x][y] 表示块x到块y的众数

g[x][y] 表示块x到块y的众数出现的次数

这三个信息可以预处理

查询答案:

答案属于{中间块的众数}∪{左右两边块中出现的数} (!!!)

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+4;
int n,blo,bel[maxn],num[maxn],cnt[204][maxn],a[maxn],val[maxn],f[204][204],g[204][204];
struct node{
    int val,pos;
}t[maxn];
bool operator < (const node &x,const node &y){
    return x.val<y.val;
}
inline int query(int l,int r){
    int ans=f[bel[l]+1][bel[r]-1];
    int mx=g[bel[l]+1][bel[r]-1];
    memset(num,0,sizeof(num));
    for(int i=l;i<=min(bel[l]*blo,r);i++) num[a[i]]++;
    for(int i=max(l,(bel[r]-1)*blo+1);i<=r;i++) num[a[i]]++;
    int tmp=0;
    for(int i=l;i<=min(bel[l]*blo,r);i++){
        if(bel[l]==bel[r]){
            tmp=num[a[i]];
        }else{
            tmp=num[a[i]]+cnt[bel[r]-1][a[i]]-cnt[bel[l]][a[i]];
        }
        if(tmp>mx||(tmp==mx&&a[i]<ans)) ans=a[i],mx=tmp;
    }
    for(int i=max(l,(bel[r]-1)*blo+1);i<=r;i++){
        tmp=num[a[i]]+cnt[bel[r]-1][a[i]]-cnt[bel[l]][a[i]];
        if(tmp>mx||(tmp==mx&&a[i]<ans)) ans=a[i],mx=tmp;
    }
    return ans;
}
int main(){
    scanf("%d",&n);
    int q;
    scanf("%d",&q);
    blo=sqrt(n);
    for(int i=1;i<=n;i++){
        bel[i]=(i-1)/blo+1;
        scanf("%d",&t[i].val);
        t[i].pos=i;
    }
    sort(t+1,t+n+1);
    int id=0;
    for(int i=1;i<=n;i++){
        if(t[i].val!=t[i-1].val||i==1) id++;
        a[t[i].pos]=id;
        val[id]=t[i].val;
    }
    for(int i=1;i<=n;i++){//cnt[i][j]
        num[a[i]]++;
        if(i==bel[i]*blo||i==n) memcpy(cnt[bel[i]],num,sizeof(num));
    }
    for(int i=1;i<=bel[n];i++){//g,f
        memset(num,0,sizeof(num));
        int mx=0,ans=0;
        for(int j=(i-1)*blo+1;j<=n;j++){
            num[a[j]]++;
            if(num[a[j]]>mx||(num[a[j]]==mx&&a[j]<ans)){
                mx=num[a[j]];
                ans=a[j];
            }
            if(j==n||j%blo==0){
                f[i][bel[j]]=ans;
                g[i][bel[j]]=mx;
            }
        }
    }
    int lastans=0;
    for(int i=1;i<=q;i++){
        int l,r;scanf("%d%d",&l,&r);
        l=(l+lastans-1)%n+1,r=(r+lastans-1)%n+1;
        if(l>r) swap(l,r);
        lastans=val[query(l,r)];
        printf("%d
",lastans);
    }
}

 

以上是关于Luogu4168 [Violet]蒲公英的主要内容,如果未能解决你的问题,请参考以下文章

题解luogu4168 [Violet]蒲公英

[Luogu P4168] [Violet]蒲公英 (分块)

p4168 [Violet]蒲公英(分块)

P4168 [Violet]蒲公英 分块

luogu4168蒲公英(区间众数)

蒲公英