Codeforces Round #650 (Div. 3) E 题解

166 阅读1分钟

题目链接

思路

本质上是凑出一个最小循环节为kk的因数的字符串,枚举循环节长度和循环节个数,判断能否凑出来,并用二者乘积维护答案。

代码

#include<bits/stdc++.h>
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
#define bl(u,i) for(int i=head[u];i;i=e[i].nxt)
#define LLM LONG_LONG_MAX
#define LLm LONG_LONG_MIN
#define pii pair<ll,ll> 
typedef long long ll;
typedef double db;
using namespace std;
const ll INF=0x3f3f3f3f;
inline void In(ll _,...)
{
	va_list lis;
	va_start(lis,_);
	while(_--)
		scanf("%lld",va_arg(lis,ll*));
}
inline void Out(ll _,...)
{
	va_list lis;
	va_start(lis,_);
	while(_--)
		printf("%lld\n",va_arg(lis,ll));
}
inline void Out_(ll _,...)
{
	va_list lis;
	va_start(lis,_);
	while(_--)
		printf("%lld ",va_arg(lis,ll));
}
ll n,k;
string s;
void solve()
{
	In(2,&n,&k);
	cin>>s;
	vector<ll> ve(30,0);
	for(auto k:s)
		ve[k-'a'+1]++;
	ll ans=0;
	rep(i,1,k)
	{
		if(k%i)
			continue;
		rep(j,1,n/i)
		{
			ll sum=0;
			for(auto p:ve)
			{
				sum+=p/j;
			}
			if(sum>=i)
				ans=max(ans,(ll)i*j);
		}
	}
	cout<<ans<<endl;
}
int main()
{
	int _;
	cin>>_;
	while(_--)
	{
		solve();
	}
}