CF1367E Solution

Preface

好吧这题我早就做过了,现在又做到了,结果不会(?)

更垃圾的阅读体验


  • “重复段”是指一个段或整条项链的某个子段,满足这个段由多个该子段拼接而成。
  • “极大重复段”是指该重复段无法分出更小的重复段。

Problem

洛谷题面原题面

Solution

我们发现极大重复段的段长一定是 \(k\) 的因数。

当然极大重复段的段长也一定是项链长度(设其为 \(i\))的因数。显然项链长度也是可以枚举的。

所以我们可以设整条项链的某个重复段的长度 \(d\)\(\gcd(k,i)\),然后计算这个重复段的长度合不合法。

具体的,我们尽可能多的往每个重复段里平均分配珠子,也就是对于某种有 \(x\) 个的珠子,往每个重复段里分配 \(\lfloor x/\frac{i}{d} \rfloor\) 个珠子,然后计算珠子的数量能否凑出 \(d\) 个。

至于为什么我们设 \(d\) 为最大的合法的 \(d\)(即 \(\gcd(k,i)\)),可以看下面的解释。

  • 对于某种有 \(x\) 个的珠子,得到分配的珠子数量是 \(\lfloor x/\frac{i}{d} \rfloor \times \frac{i}{d}\) 个;
  • 换言之,没得到分配的珠子数量是 \(( x \bmod \frac{i}{d} )\) 个;
  • \(i/\gcd(k,i)=y\),因为所有可能的 \(d\) 都是 \(\gcd(k,i)\) 的因数,所以所有可能的 \(i/d\) 都是 \(y\) 的倍数。
  • 可以证明对于任何合法的 \(d\),都有 \(x \bmod \frac{i}{d} \ge x \bmod y\)

我们相当于要证明:若 \(a\)\(b\) 的倍数,则对任意正整数 \(c\),都有 \((c \bmod a \ge c \bmod b)\)
\(a = m b\),其中 \(m\) 为正整数。对任意正整数 \(c\),由带余除法可得:

\[c = q a + r_a,\quad 0 \le r_a < a \]

\[c = p b + r_b,\quad 0 \le r_b < b \]

这里 \(r_a = c \bmod a\)\(r_b = c \bmod b\)
\(a = m b\) 代入第一个等式:

\[c = qm b + r_a \]

根据带余除法的性质,\(\forall qm\le p\),所以 \(\forall r_a\ge r_b\)。证毕。

Code

代码在这里喵~

#include<bits/stdc++.h>
using namespace std;
int n,K;
string s;
int cnt[26];
void man(){
	memset(cnt,0,sizeof cnt);
	cin>>n>>K;
	cin>>s;
	for(int i=1;i<=n;i++){
		int k=s[i-1]-'a';
		cnt[k]++;
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		int d=__gcd(i,K);
		int res=0;
		for(int j=0;j<26;j++){
			res+=cnt[j]/(i/d);
		}
		if(res>=d) ans=i;
	}
	cout<<ans<<'\n';
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	int T;cin>>T;
	while(T--) man();
	return 0;
}

Postscript

写题解不易喵,点个赞好不好喵~

posted @ 2026-05-04 21:36  NiYqaq  阅读(18)  评论(0)    收藏  举报