P8330 [ZJOI2022] 众数
Solution#
区间加这个操作看起来很阴间,实际上区间加不会改变区间内元素值的相对关系,所以答案就是区间内的众数出现次数加上区间外的众数出现次数。
操作区间两边如果都有值,那么这两个值相等一定是不劣的,因为如果我们希望
也就是说,当操作区间的左端点
我们发现如果这样暴力枚举右端点,枚举次数仅与
对于
对于
于是就只剩下了
总时间复杂度为
Code#
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define re register
namespace IO{
const int sz=1<<20;
char a[sz+5],b[sz+5],*p1=a,*p2=a,*t=b,p[105];
inline char gc(){
return p1==p2?(p2=(p1=a)+fread(a,1,sz,stdin),p1==p2?
EOF:*p1++):*p1++;
}
il int read(){
int f=1,x=0; char c=gc();
for(;c<'0'||c>'9';c=gc())if(c=='-') f*=-1;
for(;c>='0'&&c<='9';c=gc())x=x*10+(c-'0');
return x*f;
}
inline void flush(){fwrite(b,1,t-b,stdout),t=b; }
inline void pc(char x){*t++=x; if(t-b==sz) flush(); }
template<class T> void write(T x,char c='\n'){
if(x==0) pc('0'); int t=0;
if(x<0) pc('-'),x*=-1;
for(;x;x/=10) p[++t]=x%10+'0';
for(;t;--t) pc(p[t]); pc(c);
}
struct F{~F(){flush();}}f;
}
using IO::read;
using IO::write;
const int N=2e5+10,T=450;
int Tc,n,a[N],b[N],V;
int R[T+5][N],sum[N],mn[N];
int ans[N],siz[N],cnt[N],pos[N];
vector<int>v[N];
#define pb emplace_back
il void Solve_1(int x,int y){
re int mn=0,res=-n;
for(re int i=0;i<siz[y];i++)
mn=min(mn,i-sum[v[y][i]]),res=max(res,i+1-sum[v[y][i]]-mn);
ans[x]=max(ans[x],siz[x]+res);
}
il void Solve_2(int x,int y){
re int mn=0,res=-n;
for(re int i=0;i<siz[y];i++)
res=max(res,sum[v[y][i]]-i-mn),mn=min(mn,sum[v[y][i]]-i-1);
res=max(res,siz[x]-siz[y]-mn);
ans[y]=max(ans[y],siz[y]+res);
}
il void Solve_gt(int i){
for(re int j=1;j<=n;j++)sum[j]=sum[j-1]+(a[j]==i);
for(re int j=1;j<=V;j++)if(i^j)Solve_1(i,j);
for(re int j=1;j<=V;j++)if(siz[j]<=T)Solve_2(i,j);
}
il void Init_le(int x){
for(re int i=1;i<=V;i++)cnt[i]=0;
re int mx=0;
for(re int i=1;i<=n;i++){
if(i^1)cnt[a[i-1]]--,mx-=(a[i-1]==a[R[x][i-1]]);
R[x][i]=R[x][i-1];
while(R[x][i]<=n&&mx^x)mx=max(mx,++cnt[a[++R[x][i]]]);
}
}
il void Solve_le(){
for(re int i=1;i<=V;i++)if(siz[i]<=T)v[i].pb(n+1);
re int l=0,mx=0;
for(re int i=1;i<=V;i++)cnt[i]=0;
for(re int r=2;r<=n;r++)
ans[a[r]]=max(ans[a[r]],siz[a[r]]-pos[r]+(mx=max(mx,++cnt[a[r-1]])));
for(l=1;l<n;l++){
if(siz[a[l]]>T)continue;
re int res=0;
for(re int i=pos[l]+1;i<=siz[a[l]];i++){
re int r=v[a[l]][i];
while(res<T&&R[res+1][l+1]<r)res++;
ans[a[l]]=max(ans[a[l]],res+siz[a[l]]-i+pos[l]+1);
}
}
}
il void MrcFrst(){
n=read();
for(re int i=1;i<=n;i++)b[i]=a[i]=read();
sort(b+1,b+1+n),V=unique(b+1,b+1+n)-b-1;
for(re int i=1;i<=V;i++)v[i].clear();
for(re int i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+1+V,a[i])-b,pos[i]=v[a[i]].size(),v[a[i]].pb(i);
for(re int i=1;i<=V;i++)ans[i]=siz[i]=v[i].size();
for(re int i=1;i<=V;i++)if(siz[i]>T)Solve_gt(i);
for(re int i=1;i<=T;i++)Init_le(i);
Solve_le();
re int res=0;
for(re int i=1;i<=V;i++)res=max(res,ans[i]);
write(res);
for(re int i=1;i<=V;i++)if(ans[i]==res)write(b[i]);
}
int main(){
// freopen("my.in","r",stdin);
// freopen("my.out","w",stdout);
Tc=read();
while(Tc--)MrcFrst();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)