Loj#6285. 数列分块入门 9

求在线区间最小众数

原理:http://hzwer.com/8053.html 已经讲了。

就说一说我遇到的几个问题

主要在这里

for(i=1;i<=k;i++) {
	memset(cnt,0,sizeof cnt);
	max_cnt=0;
	for(j=L[i];j<=n;j++) {
		cnt[a[j]]++;
		if(f[i][F[j]]==0) f[i][F[j]]=f[i][F[j]-1]; 
		if(cnt[a[j]]>max_cnt||(cnt[a[j]]==max_cnt&&a[j]<f[i][F[j]])) {
			max_cnt=cnt[a[j]];
			f[i][F[j]]=a[j];
		}
	}
}
  • (f[i][F[j]]) 当中间容器会出现 其没被更新的情况 ,加上这句即可

  • if(f[i][F[j]]==0) f[i][F[j]]=f[i][F[j]-1]; 
    
  • 另外就是 (f[][]) 的初值是零,(cnt[a[j]]==max_cnt&&a[j]<f[i][F[j]])​无法更新。

  • 解决方法同上

完整代码

#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long
#define rint register int 
namespace FastIO
{
char c;
bool sign;
template<class T>
inline void read(T &x)
{
	x=0;
	sign=false;
	for(c=getchar();c<'0'||c>'9';c=getchar()) 
		if(c=='-') 
			sign=true;
	for(;c>='0'&&c<='9';c=getchar())
		x=(x<<1)+(x<<3)+(c&15);
	if(sign) x=~x+1;
 	return;
}
template<class T>
void print(T x)
{
	if(x<0) putchar('-'),x=~x+1;
	if(x>9) print(x/10);
	putchar(x%10+'0');
	return;
}
}
using FastIO::read;
using FastIO::print;
//================================================
using namespace std;
const int N=100000+5;
const int SQ=1000+5;
int n;
int a[N];
struct block
{
	int siz,k;
	int f[SQ][SQ];
	int L[SQ],R[SQ],F[N];
	int cnt[N];
	vector<int> c[N];
	inline void Build()
	{
		rint i,j;
		siz=pow(n,0.40);
		k=n/siz+(n%siz>0);
		for(i=1;i<=k;i++) {
			L[i]=R[i-1]+1;
			R[i]=i*siz;
		}
		for(i=1;i<=k;i++) 
			for(j=L[i];j<=R[i];j++) 
				F[j]=i;
		for(i=1;i<=n;i++) 
			c[a[i]].push_back(i);
		int max_cnt;
		for(i=1;i<=k;i++) {
			memset(cnt,0,sizeof cnt);
			max_cnt=0;
			for(j=L[i];j<=n;j++) {
				cnt[a[j]]++;
				if(f[i][F[j]]==0) f[i][F[j]]=f[i][F[j]-1]; 
				if(cnt[a[j]]>max_cnt||(cnt[a[j]]==max_cnt&&a[j]<f[i][F[j]])) {
					max_cnt=cnt[a[j]];
					f[i][F[j]]=a[j];
				}
			}
		}			
		return;
	}
	inline int count(const int &key,const int &x,const int &y)
	{
		return (int)(upper_bound(c[key].begin(),c[key].end(),y)-lower_bound(c[key].begin(),c[key].end(),x));
	}
	inline int query(const int &x,const int &y)
	{
		rint i;
		rint res=0,mx=0,tmp=0;
		if(F[x]==F[y]) {
			for(i=x;i<=y;i++) {
				tmp=count(a[i],x,y);
				if(tmp>mx||(tmp==mx&&a[i]<res)) {
					mx=tmp;
					res=a[i];
				} 
			}
			return res;
		}
		res=f[F[x]+1][F[y]-1];
		mx=count(res,x,y);
		for(i=x;i<=R[F[x]];i++) {
			tmp=count(a[i],x,y);
			if(tmp>mx||(tmp==mx&&a[i]<res)) {
				mx=tmp;
				res=a[i];
			} 
		}
		for(i=L[F[y]];i<=y;i++) {
			tmp=count(a[i],x,y);
			if(tmp>mx||(tmp==mx&&a[i]<res)) {
				mx=tmp;
				res=a[i];
			}
		}
		return res;
	}
}B;
vector<int> v;
int main()
{
//	freopen("1.in","r",stdin);
	rint i;
	int x,y;
	read(n);
	for(i=1;i<=n;i++) {
		read(a[i]);
		v.push_back(a[i]);
	}
	sort(v.begin(),v.end());
	v.erase(unique(v.begin(),v.end()),v.end());
	for(i=1;i<=n;i++) 
		a[i]=(int)(lower_bound(v.begin(),v.end(),a[i])-v.begin())+1;
	B.Build();
	for(i=1;i<=n;i++) {
		read(x); read(y);
		print(v[B.query(x,y)-1]); putchar('
');
	}
	return 0;
}
原文地址:https://www.cnblogs.com/cjl-world/p/13162608.html