题目大意

现在需要使用从小写字母 aa 开始的 kk 种字符,构造一个长度为 nn 的字符串 ss,使满足 i,j[1,n1]iji,j\in[1,n-1],i\neq jai=aj,ai+1=aj+1a_i=a_j,a_{i+1}=a_{j+1} 的数对的数量最少。

其中 1n2×105,1k261\le n \le 2\times 10^5,1\le k \le 26

思路

在使用 kk 总字符的情况下,可以构造长度为 22 的字符串的种类为 Ak2\operatorname{A}^2_k

但是因为在构造时上一队的字符会和这一对的字符组成以前出现过的字符。

为了避免这个情况,我们可以规定每一对里两个字母 sis_isi+1s_{i+1} 满足 si<si+1s_i < s_{i+1},所以当与上一组组合时就一定会满足 si1>sis_{i-1}>s_i 自然就不会出现重复的情况。

因为在如果所有的 sis_i 都小于 si+1s_{i+1} 时,我们就会漏掉一种 si=si+1s_i=s_{i+1} 的情况,所以就需要特别的在每一个 si+1=si+1s_i+1=s_{i+1} 的前面添加一个 sis_i

因为 i=1k2×(ki)+1\sum_{i=1}^k 2\times(k-i) +1

=i=1k2×k2×i+1=\sum_{i=1}^k 2\times k-2\times i+1

=2×k22×k×(1+k)2+k= 2\times k^2-2\times \frac{k\times (1+k)}{2}+k

=2×k2kk2+k=2\times k^2 -k-k^2+k

=k2=k^2

所以,使用以上方法构造的没有重复的序列最长为 k2k^2

假设第 ii 组字符串出现的次数为 cnticnt_i,那么一定满足 i=1k2cnti\sum_{i=1}^{k^2} cnt_i 是一定的。

代价为

cost=i=1kcnti22n12cost=\sum _{i=1}^k \frac{cnt_i^2}{2}-\frac{n-1}{2}

要使 costcost 最小,那么所有的 cnticnt_i 应该越相近越小,所以在 n>k2n>k^2 的时候就应该将原来长度为 k2k^2 的字符串在后面进行重复。

直接模拟上面的操作,时间复杂度为 O(m)O(m)

AC Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n,m,cnt,a[30][30];
void solve(){
	cin>>n>>m;
	while(cnt<n){
		for(int i=0;i<m;i++){
			if(cnt>=n) break;
			putchar('a'+i);
			cnt++;
			for(int j=i+1;j<m;j++){
				if(cnt>=n) break;
				putchar('a'+i);
				cnt++;
				if(cnt>=n) break;
				putchar('a'+j);
				cnt++;
				if(cnt>=n) break;
			}
		}
	}
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
	int T=1;
	while(T--) solve();
    return 0;
}