【CF1511D】Min Cost String 题目 思路 代码

题目链接:http://codeforces.com/problemset/problem/1511/D
定义一个字符串 (s) 的花费为满足 (s_i=s_j)(s_{i+1}=s_{j+1}) 的数对 ((i,j)) 的数量((0 leq i<j<|s|-1)
现在需要使用从小写字母 (a) 开始的 (m) 种字符,构造一个长度为 (n) 的字符串,且要求花费最小。输出任意一种即可。
(nleq 3 imes 10^5,mleq 26)

思路

假设 (m=5),考虑如下构造

[eeaebeced dadbdc cacb ba abcde ]

我们发现这样循环一次恰好把 (asim e) 所有组合都得到了一遍。
然后不断重复这个循环直到字符串长度为 (n) 即可。注意每次循环第一个字符和最后一个字符其实是同一个,省掉一个即可。
时间复杂度 (O(n))

代码

#include <bits/stdc++.h>
#define mp make_pair
#define ST first
#define ND second
#define write(x) { putchar(x+'a'-1); n--; if (!n) return 0; }
using namespace std;
typedef long long ll;
typedef long double ld;

const int N=200010;
int Q,n,m,a[N],b[N];

int main()
{
//	freopen("data.txt","r",stdin);
	scanf("%d%d",&n,&m);
	while (1)
	{
		write(m);
		for (int i=m;i>1;i--)
		{
			write(i);
			for (int j=1;j<i-1;j++)
			{
				write(j);
				write(i);
			}
			write(i-1);
		}
		for (int i=1;i<m;i++) write(i);
	}
}