Loj 6285. 数列分块入门 9
Posted kls123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Loj 6285. 数列分块入门 9相关的知识,希望对你有一定的参考价值。
链接:
https://loj.ac/problem/6285
思路:
离散化处理下就好了,具体解释在代码里、
ps:
小新新别看了,你学不会的
实现代码:
#include<bits/stdc++.h> using namespace std; const int M = 1e5 + 10; int n,block,idx,a[M],bl[M],f[510][510],val[M],cnt[M]; vector<int>ve[M]; void pre(int x){ //预处理 memset(cnt,0,sizeof(cnt)); int mx = 0, ans = 0; for(int i = (x - 1)*block+1;i <= n;i ++){ cnt[a[i]]++; int t = bl[i]; if(cnt[a[i]] > mx||(cnt[a[i]]==mx&&val[a[i]]<val[ans])) //如果在当前区间出现次数比最大值或者和最大值一样但是值比最大值小,那么更新最大值 ans = a[i],mx = cnt[a[i]]; f[x][t] = ans; //代表 x块 到 t块中的最小众数 } } int query(int l,int r,int x){ //在ve[ai]二分寻找在l,r区间的a[i]的数量 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 l,int r){ int ans,mx; ans = f[bl[l]+1][bl[r]-1]; //完整块的查询 mx = query(l,r,ans); //非完整块的查询 for(int i = l;i <= min(bl[l]*block,r);i ++){ int t = query(l,r,a[i]); if(t > mx||(t == mx&&val[a[i]] < val[ans])) ans = a[i],mx = t; } if(bl[l] != bl[r]){ for(int i = (bl[r]-1)*block+1;i <= r;i ++){ int t = query(l,r,a[i]); if(t > mx||(t == mx&&val[a[i]] < val[ans])) ans = a[i],mx = t; } } return ans; } map<int,int>mp; int main() { int l,r; scanf("%d",&n); block = sqrt(n); for(int i = 1;i <= n;i ++){ scanf("%d",&a[i]); if(!mp[a[i]]){ mp[a[i]] = ++idx; //离散化 val[idx] = a[i]; //val数组储存离散化之前的值 } a[i] = mp[a[i]]; //离散化 ve[a[i]].push_back(i); //将每个a[i]出现的下标存到a[i]对应的vecotr里 } for(int i = 1;i <= n;i ++) bl[i] = (i - 1)/block + 1; for(int i = 1;i <= bl[n];i ++) pre(i); //预处理每一个块 for(int i = 1;i <= n;i ++) { scanf("%d%d",&l,&r); if(l > r) swap(l,r); printf("%d ",val[query(l,r)]); } return 0; }
以上是关于Loj 6285. 数列分块入门 9的主要内容,如果未能解决你的问题,请参考以下文章