P9978 [USACO23DEC] Cycle Correspondence S 题解
题目大意
两个环呈包含关系,每个环上的元素都不相同,两个环可以自由旋转,问怎么使得重合部分最多。
解题思路
显然,我们对于环
AC 代码
#include<math.h>
#include<time.h>
#include<stdio.h>
#include<algorithm>
#define ll long long
#define N 1000005
int n,k,a[N],b[N];
int tong[N],ans;
int cnt1[N],cnt2[N];
int pa[N],pb[N],pf[N];
int fb[N];
namespace Case1{
inline void Main(){
for(register int i=k+1;i<=2*k;++i)
b[i]=b[i-k];
for(register int i=1;i<=k;++i){
int cnt=0;
for(register int j=i;j<k+i;++j)
if(b[j]==a[j-i+1]) ++cnt;
ans=std::max(ans,cnt);
}
for(register int i=1;i<=k;++i)
std::swap(b[i],b[k*2-i+1]);
for(register int i=1;i<=k;++i){
int cnt=0;
for(register int j=i;j<k+i;++j)
if(b[j]==a[j-i+1]) ++cnt;
ans=std::max(ans,cnt);
}
}
}
namespace Case2{
inline void Main(){
for(register int i=1;i<=k;++i)
fb[k-i+1]=b[i];
for(register int i=1;i<=k;++i)
pa[a[i]]=i,pb[b[i]]=i,pf[fb[i]]=i;
for(register int i=1;i<=k;++i){
if(pa[b[i]])
++cnt1[(pa[b[i]]-pb[b[i]]+k)%k];
if(pa[fb[i]])
++cnt2[(pa[fb[i]]-pf[fb[i]]+k)%k];
}
for(register int i=0;i<k;++i)
ans=std::max({ans,cnt1[i],cnt2[i]});
}
}
inline void work(){
scanf("%d%d",&n,&k);
for(register int i=1;i<=k;++i)
scanf("%d",&a[i]);
for(register int i=1;i<=k;++i)
scanf("%d",&b[i]);
for(register int i=1;i<=k;++i)
tong[a[i]]=tong[b[i]]=1;
int res=0;
for(register int i=1;i<=n;++i)
if(tong[i]==0) ++res;
if(k<=10000) Case1::Main();
else Case2::Main();
ans=ans+res;printf("%d",ans);
}signed main(){
srand(114514);
srand(rand());
srand(time(0));
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
work();return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下