在线版区间众数 hzw的代码。。
Posted zsben991126
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在线版区间众数 hzw的代码。。相关的知识,希望对你有一定的参考价值。
/* 查询区间众数,要求强制在线 设有T个块 1.众数只可能在大块[L,R]里或者两端[l,L) (R,r]里出现 2.大块的众数只要预处理打表一下即可,复杂度n*T(这样的区间有T*T个) 3.两端的众数需要枚举每个元素,然后查询这个元素在区间[l,r]里出现的次数 用一个vector记录每个值出现的位置,然后用二分找其在区间[l,r]出现的次数即可 这部分每次查询的复杂度是N/T*logN, 块长取sqrt(nlogn) */ #include<bits/stdc++.h> using namespace std; #define maxn 100005 int id,n,len,pos[maxn],v[maxn],val[maxn],f[500][500]; vector<int>ve[maxn]; map<int,int>mp;//哈希表 int cnt[maxn]; void pre(int p){//处理第p块到n整块区间众数 memset(cnt,0,sizeof cnt); int mx=0,ans=0; for(int i=(p-1)*len+1;i<=n;i++){ cnt[v[i]]++; int t=pos[i]; if(cnt[v[i]]>mx || cnt[v[i]]==mx && val[v[i]]<val[ans]) ans=v[i],mx=cnt[v[i]]; f[p][t]=ans; } } int query(int l,int r,int x){//查询[l,r]区间x出现了几次 int t=upper_bound(ve[x].begin(),ve[x].end(),r)-lower_bound(ve[x].begin(),ve[x].end(),l); return t; } int query(int a,int b){ int ans,mx,p=pos[a],q=pos[b]; ans=f[p+1][q-1]; mx=query(a,b,ans); for(int i=a;i<=min(p*len,b);i++){ int t=query(a,i,v[i]); if(t>mx || t==mx&&val[v[i]]<val[ans]) ans=v[i],mx=t; } if(p!=q) for(int i=(q-1)*len+1;i<=b;i++){ int t=query(i,b,v[i]); if(t>mx || t==mx&&val[v[i]]<val[ans]) ans=v[i],mx=t; } return ans; } int main(){ cin>>n;len=200; for(int i=1;i<=n;i++){ cin>>v[i]; if(mp[v[i]]==0){ mp[v[i]]=++id; val[id]=v[i]; } v[i]=mp[v[i]]; ve[v[i]].push_back(i); } for(int i=1;i<=n;i++) pos[i]=(i-1)/len+1; for(int i=1;i<=pos[n];i++) pre(i);//预处理 for(int i=1;i<=n;i++){ int a,b; cin>>a>>b; if(a>b)swap(a,b); cout<<val[query(a,b)]<<endl; } }
以上是关于在线版区间众数 hzw的代码。。的主要内容,如果未能解决你的问题,请参考以下文章