ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1446D2 Frequency Problem (Hard Version)

2021-04-16 16:01:50  阅读:209  来源: 互联网

标签:ch int sqrt Frequency CF1446D2 cnt2 cnt1 Ans Problem


CF1446D2 Frequency Problem (Hard Version)(根号分治)

首先这道题有一个结论:这两个元素当中一定有一个是众数,证明略。

那么考虑对于出现次数大于等于 \(\sqrt{n}\) 的数,我们可以把这些数枚举一下,然后这样做:

把值为当前数的位置标为 1 ,把值为众数的标为 -1 ,其他的都是 0 ,然后做一遍前缀和,记录每一个前缀和值的出现的最早的位置。

于是区间的长度那就是当前位置减掉这个前缀和第一次出现的位置(这样的话这个区间和就是 0)。

这部分的数的个数不超过 \(\sqrt{n}\) 个。

接下来是对于出现次数小于 $\sqrt{n} $的数。

我们可以枚举区间当中出现次数最多的数的次数,再枚举每一个 \(r\) ,求出最小的左端点 \(L_r\) ,整个过程是一个双指针。

可以参考这片题解

代码:

#include<bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T &x){
	x=0;bool f=false;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	x=f?-x:x;
	return ;
}
template <typename T>
inline void write(T x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10^48);
	return ;
}
const int N=2e5+5,T=505,INF=1e9+7;
int n,Maxn,cnt,Ans,S,val;
int a[N],Num[N],sum[N],t[N*2],cnt1[N],cnt2[N];
vector<int>v;
inline void Modify(int x,int v){cnt2[cnt1[x]]--,cnt1[x]+=v,cnt2[cnt1[x]]++;}
int main(){
	read(n),S=sqrt(n);
	for(int i=1;i<=n;i++) read(a[i]),Num[a[i]]++;
	for(int i=1;i<=n;i++){
		if(Num[i]==Maxn) cnt++;
		if(Num[i]>Maxn) cnt=1,Maxn=Num[i];
	}
	if(cnt>1){write(n);return 0;}
	for(int i=1;i<=n;i++){
		if(Num[i]==Maxn) val=i;
		else if(Num[i]>S) v.push_back(i);
	}
	for(int i=0;i<v.size();i++){
		int k=v[i];
		for(int j=1;j<=n;j++) sum[j]=sum[j-1]+(a[j]==k? -1:(a[j]==val? 1:0));
		for(int j=-n;j<=n;j++) t[n+j]=INF;
		for(int j=1;j<=n;j++) Ans=max(Ans,j-t[n+sum[j]]+1),t[n+sum[j-1]]=min(t[n+sum[j-1]],j);
	}
	for(int i=1;i<=S;i++){
		for(int j=1;j<=n;j++) cnt1[j]=cnt2[j]=0;
		int l=1,r=0;
		while(r<n){
			r++,Modify(a[r],1);
			while(cnt1[a[r]]>i) Modify(a[l],-1),l++;
			if(cnt2[i]>=2) Ans=max(Ans,r-l+1);
		}
	}
	write(Ans);
	return 0;
}

标签:ch,int,sqrt,Frequency,CF1446D2,cnt2,cnt1,Ans,Problem
来源: https://www.cnblogs.com/Akmaey/p/14667353.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有