蒲公英
Posted 2462478392lee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蒲公英相关的知识,希望对你有一定的参考价值。
题意:给N个数,求一个区间内的众数。
思路:分块,分成sqrt(t*log2(n)))块,先预处理出每一个块到每个块中的众数,离散化,然后把询问区间分三段,第一段为l到l所在块的终止,第二段为每一段块,第三段为r块的开始到r,然后第二段用预处理的数组就能得出,第一三段,二分vector记录的下标求众数。
#include<cstring> #include<algorithm> #include<vector> #include<map> #include<queue> #include<cstdio> #include<cmath> #define ll long long #define lowbit(x) x&(-x) using namespace std; const int N=1e6+10; int n,t,block; int a[N],f[N],b[N]; vector<int> g[N]; int c[N],d[1000][1000]; void build() block=max(1,(int)(n/sqrt(t*log2(n)))); for(int i=1;i<=n;i++) b[i]=(i-1)/block+1; int Count(int l,int r,int val) int t=upper_bound(g[val].begin(),g[val].end(),r)-lower_bound(g[val].begin(),g[val].end(),l); return t; void pre(int x) memset(c,0,sizeof(c)); int mx=-1,ans=0; for(int i=(x-1)*block+1;i<=n;i++) c[a[i]]++; if(c[a[i]]>mx||(c[a[i]]==mx&&a[i]<ans)) ans=a[i]; mx=c[a[i]]; d[x][b[i]]=ans;//代表x到b[i]块的众数。 int query(int l,int r) int ans=d[b[l]+1][b[r]-1]; int mx=Count(l,r,ans); int cnt=0; int up=min(r,b[l]*block); for(int i=l;i<=up;i++) cnt=Count(l,r,a[i]); if(cnt>mx||(cnt==mx&&f[ans]>f[a[i]])) mx=cnt; ans=a[i]; if(b[l]!=b[r]) for (int i=(b[r]-1)*block+1;i<=r;i++) cnt=Count(l,r,a[i]); if(cnt>mx||(cnt==mx&&ans>a[i])) mx=cnt; ans=a[i]; return ans; signed main() scanf("%d%d",&n,&t); for(int i=1;i<=n;i++) scanf("%d",&a[i]); f[i]=a[i]; build(); sort(f+1,f+n+1); int m=unique(f+1,f+n+1)-f-1; for(int i=1;i<=n;i++) a[i]=lower_bound(f+1,f+m+1,a[i])-f; g[a[i]].push_back(i); for(int i=1;i<=b[n];i++) pre(i); int ans=0; while(t--) int l,r; scanf("%d%d",&l,&r); l=(l+ans-1)%n+1; r=(r+ans-1)%n+1; if(l>r) swap(l,r); ans=f[query(l,r)]; printf("%d\n",ans);
以上是关于蒲公英的主要内容,如果未能解决你的问题,请参考以下文章