加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

P4168 [Violet]蒲公英(分块)

发布时间:2020-12-15 07:48:58 所属栏目:Java 来源:网络整理
导读:询问区间最小的众数 先离散化,nsqrt(n)预处理,然后我用vector存了每个值对应的位置,每次二分地找某个值在指定区间当中出现了几次 不开O2疯狂TLE,开了就过了,vector大法好, 可以顶平衡树 代码: #includebits/stdc++.h using namespace std; const int

询问区间最小的众数

先离散化,nsqrt(n)预处理,然后我用vector存了每个值对应的位置,每次二分地找某个值在指定区间当中出现了几次

不开O2疯狂TLE,开了就过了,vector大法好,可以顶平衡树

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=500005;
const int inf=0x3f3f3f3f;
inline int read(){
    char ch=getchar();int s=0,w=1;
    while(ch<48||ch>57){if(ch==-)w=-1;ch=getchar();}
    while(ch>=48&&ch<=57){s=(s<<1)+(s<<3)+ch-48;ch=getchar();}
    return s*w;
}
inline void write(int x){
    if(x<0)putchar(-),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+48);
}

int n,m,lastans=0,l,r;
int a[maxn],b[maxn];
int cnt[maxn],ans[1000][1000],num[1000][1000];
int id[maxn],from[1000],to[1000],tot;
vector<int> pos[maxn];

void pre(){
    tot=sqrt(n);
    for(int i=1;i<=tot;++i){
        from[i]=(i-1)*tot+1;
        to[i]=i*tot;
    }
    if(to[tot]<n) tot++,from[tot]=to[tot-1]+1,to[tot]=n;
    for(int i=1;i<=tot;++i)
        for(int j=from[i];j<=to[i];++j) id[j]=i;
    for(int i=1;i<=tot;++i){
        for(int j=i;j<=tot;++j){
            num[i][j]=-inf,ans[i][j]=inf;
            for(int k=from[i];k<=to[j];++k) cnt[a[k]]=0;
            for(int k=from[i];k<=to[j];++k){
                cnt[a[k]]++;
                if(cnt[a[k]]>num[i][j]){
                    num[i][j]=cnt[a[k]];
                    ans[i][j]=a[k];
                }
                else if(cnt[a[k]]==num[i][j]&&
                a[k]<ans[i][j])
                    ans[i][j]=a[k];
            }
        }
    }
    for(int i=1;i<=n;++i)
        pos[a[i]].push_back(i);
}

void solve(){
//    l=(l+lastans-1)%n+1;
//    r=(r+lastans-1)%n+1;
    l^=lastans;
    r^=lastans;
    if(l>r){
        int t=l;
        l=r;
        r=t;
    }
    int tnum=-inf,tans=inf;
    int pl=id[l],pr=id[r];
    if(pl==pr){
        for(int i=l;i<=r;++i){
            int t1=lower_bound(pos[a[i]].begin(),pos[a[i]].end(),l)-pos[a[i]].begin();
            int t2=upper_bound(pos[a[i]].begin(),r)-pos[a[i]].begin();
            if(t2-t1>tnum){
                tnum=t2-t1;
                tans=a[i];
            }
            else if(t2-t1==tnum&&a[i]<tans)
                tans=a[i];
        }
    }
    else{
        tnum=num[pl+1][pr-1],tans=ans[pl+1][pr-1];
        for(int i=l;i<=to[id[l]];++i){
            int t1=lower_bound(pos[a[i]].begin(),r)-pos[a[i]].begin();
            if(t2-t1>tnum){
                tnum=t2-t1;
                tans=a[i];
            }
            else if(t2-t1==tnum&&a[i]<tans)
                tans=a[i];
        }
        for(int i=from[id[r]];i<=r;++i){
            int t1=lower_bound(pos[a[i]].begin(),r)-pos[a[i]].begin();
            if(t2-t1>tnum){
                tnum=t2-t1;
                tans=a[i];
            }
            else if(t2-t1==tnum&&a[i]<tans)
                tans=a[i];
        }
    }
//    write(b[tans]);
//    puts("");
//    lastans=b[tans];
    write(tnum);
    puts("");
    lastans=tnum;
}

int main(){
    n=read(),m=read();
    for(int i=1;i<=n;++i) a[i]=read(),b[i]=a[i];
    sort(b+1,b+1+n);
    for(int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+1+n,a[i])-b;
    pre();
    for(int i=1;i<=m;++i){
        l=read(),r=read();
        solve();
    } 
    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读